我用C語言撰寫了這個程式,它讀入一個檔案并將其列印成一個表格,該表格用垂直條對齊,包括一個頁眉和頁腳。該檔案總是有3列,但行的數量不同。每一列中的字符數量不同。我遇到的問題是,我讀進去的第一個檔案是完全對齊的,但當我讀進去的其他檔案在所有的列中都增加了尺寸時,卻沒有對齊。有什么方法可以讓它自動對齊,還是我必須每次都要手動完成?
代碼:
#include <stdio.h>/span>
#include <string.h>
#include <stdlib.h>
//常數,用于存盤可從檔案中讀取的最大記錄大小。
enum
{
///更新MAX_SIZE到如果行數超過1000。
MAX_SIZE=1024
};
//從檔案中存盤一條記錄的結構。
typedef struct
{[/span>
char define[20] 。
char octal[26] 。
char description[1000] 。
} 記錄。
//string to store the header of the table[/span
char header1[20], header2[20], header3[20] 。
//函式用于讀取檔案并回傳從檔案中讀取的最大描述長度。
int readFile(Record rec[], int *size)
{
//打開一個檔案進行輸入。
FILE *fp = fopen("input2.txt", "r") 。
//檢查檔案是否成功打開。
if (fp == NULL)
{
printf("File could not be opened!") 。
exit(1)。
}
int i = 0;
int maxLength=0;
//讀取檔案。
//首先我們從檔案中讀取每列的標題。
fscanf(fp, "%s%s%s
", header1, header2, header3)。)
//現在我們從檔案中讀取每個記錄。
while (fscanf(fp, "s"/span>, rec[i].define) == 1)
{
fscanf(fp, "s '%[^']'", rec[i].octal, rec[i].description) 。
//找到描述的長度并更新'maxLength'。
if (strlen(rec[i].description) > maxLength)
{
maxLength = strlen(rec[i].description)。
}
//增加i的值。
i ;
}
//關閉輸入檔案
fclose(fp)。
//更新從檔案中讀取的記錄數 //更新從檔案中讀取的記錄數
*size = i;
return maxLength。
}
void printTable(Record rec[], int size, int WIDTH)
{
char p='|'。
//列印表頭
for (int i = 0; i < 22 WIDTH; i )
printf("-"/span>)。
printf("
| %-7s %c %5s %c %-*s %c
", header1, p, header2, p, WIDTH, header3,p)。)
for (int i = 0; i < 22 WIDTH; i )
printf("-"/span>)。
printf("
")。)
//列印表的資料。
for (int i = 0; i < size; i )
printf("|%-7s | %5s | %-*s |
", rec[i].define, rec[i].octal, WIDTH, rec[i].description)。)
//列印頁腳
for (int i = 0; i < 22 WIDTH; i )
printf("-"/span>)。
printf("
")。)
}
// driver function
int main()
{
//創建一個MAX_SIZE的recors陣列。
記錄recs[MAX_SIZE]。
//將recs的大小初始化為零。
int size = 0;
//呼叫readFile()函式,從檔案中讀取資料并更新recs的大小。
int WIDTH = readFile(recs, &size);
//呼叫printTable()函式,以良好的格式化方式列印表格。
printTable(recs, size, WIDTH)。
return 0。
}
檔案:
#define octal description
O_APPEND 02000 '檔案以追加模式打開'。
O_ASYNC 020000 '啟用信號驅動的I/O'/span>。
O_CLOEXEC 02000000 '為新檔案描述符啟用執行時關閉標志。
O_CREAT 0100 '如果路徑名不存在,將其作為一個普通檔案創建。
O_DIRECT 040000 '盡量減少進出該檔案的I/O的快取效果。
O_DIRECTORY 0200000 '如果路徑名不是一個目錄,導致打開失敗。
O_DSYNC 010000 '寫操作將按照同步I/O資料完整性的要求完成。'
O_EXCL 0200 '確保此呼叫創建檔案。'
O_LARGEFILE 0 '允許打開那些不能用off_t表示大小的檔案。
O_NOATIME 01000000 '當檔案被讀取(2)時,不要更新檔案的最后訪問時間(inode中的st_atime)。
O_NOCTTY 0400 '如果路徑名指向一個終端設備,它將不會成為行程的控制終端。
O_NOFOLLOW 0400000 '如果路徑名是一個符號鏈接,那么打開失敗,錯誤為ELOOP。
O_NONBLOCK 04000 '如果可能,檔案將以非阻塞模式打開。'
O_PATH 010000000 '獲得一個檔案描述符,可用于執行純粹作用于檔案描述符級別的操作。'
O_SYNC 04010000 '寫操作將根據同步I/O檔案完整性的要求完成。
O_TMPFILE 020200000 '創建一個未命名的臨時常規檔案'。
O_TRUNC 01000 '如果該檔案已經存在并且是一個普通檔案,它將被截斷為長度為0。
目前正在列印的內容:
---------------------------------------------------------------------------------------------------------------------------------
| #define | octal | description |
---------------------------------------------------------------------------------------------------------------------------------
| O_APPEND | 02000 | 檔案以追加模式打開。 |
| O_ASYNC | 020000 | 啟用信號驅動的I/O。 |
| O_CLOEXEC | 02000000 | 啟用新檔案描述符的執行關閉標志。 |
| O_CREAT | 0100 | 如果路徑名不存在,將其作為一個普通檔案創建。 |
| O_DIRECT | 040000 | 盡量減少進出該檔案的I/O的快取影響。 |
| O_DIRECTORY | 0200000 | 如果路徑名不是一個目錄,導致打開失敗。 |
| O_DSYNC | 010000 | 寫操作將根據同步I/O資料完整性的要求完成。|
| O_EXCL | 0200 | 確保此呼叫創建檔案。 |
| O_LARGEFILE | 0 | 允許打開那些大小不能用off_t表示的檔案。 |
| O_NOATIME | 01000000 | 當檔案被讀取時,不要更新檔案的最后訪問時間(inode中的st_atime)(2)。 |
| O_NOCTTY | 0400 | 如果路徑名指向一個終端設備,它將不會成為行程的控制終端。 |
| O_NOFOLLOW | 0400000 | 如果路徑名是一個符號鏈接,則打開失敗,錯誤為ELOOP。 |
| O_NONBLOCK | 04000 | 如果可能,檔案將以非阻塞模式打開。 |
| O_PATH | 010000000 | 獲得一個檔案描述符,可用于執行純粹作用于檔案描述符級別的操作。 |
| O_SYNC | 04010000 | 寫操作將根據同步I/O檔案完整性的要求完成。|
| O_TMPFILE | 020200000 | 創建一個未命名的臨時常規檔案。 |
| O_TRUNC | 01000 | 如果該檔案已經存在并且是一個普通檔案,它將被截斷為長度0. |
---------------------------------------------------------------------------------------------------------------------------------
它應該是什么樣子的:
-----------------------------------------------------------------------------------------------------------------------------------------
|
-----------------------------------------------------------------------------------------------------------------------------------------
| O_APPEND | 02000 | 檔案以追加模式打開。 |
| O_ASYNC | 020000 | 啟用信號驅動的I/O。 |
| O_CLOEXEC | 02000000 | 啟用新檔案描述符的執行關閉標志。 |
| O_CREAT | 0100 | 如果路徑名不存在,將其作為一個普通檔案創建。 |
| O_DIRECT | 040000 | 盡量減少進出該檔案的I/O的快取影響。 |
| O_DIRECTORY | 0200000 | 如果路徑名不是一個目錄,導致打開失敗。 |
| O_DSYNC | 010000 | 寫操作將根據同步I/O資料完整性的要求完成。|
| O_EXCL | 0200 | 確保此呼叫創建檔案。 |
| O_LARGEFILE | 0 | 允許打開那些大小不能用off_t表示的檔案。 |
| O_NOATIME | 01000000 | 當檔案被讀取時,不要更新檔案的最后訪問時間(inode中的st_atime)(2)。 |
| O_NOCTTY | 0400 | 如果路徑名指向一個終端設備,它將不會成為行程的控制終端。 |
| O_NOFOLLOW | 0400000 | 如果路徑名是一個符號鏈接,則打開失敗,錯誤為ELOOP。 |
| O_NONBLOCK | 04000 | 如果可能,檔案將以非阻塞模式打開。 |
| O_PATH | 010000000 | 獲得一個檔案描述符,可用于執行純粹作用于檔案描述符級別的操作。 |
| O_SYNC | 04010000 | 寫操作將根據同步I/O檔案完整性的要求完成。|
| O_TMPFILE | 020200000 | 創建一個未命名的臨時常規檔案。 |
| O_TRUNC | 01000 | 如果該檔案已經存在并且是一個普通檔案,它將被截斷為長度0. |
-----------------------------------------------------------------------------------------------------------------------------------------
uj5u.com熱心網友回復:
示例函式。
struct a>
{
char *s ; int x; char *y;
} a[] = {
{"Hello"/span>, 435342435432, "1"/span>}。
{"dfgsfdgdgdfgdf", 5, "1fdsfsdfs">,}
{"Hellodfds", 43534, "sdffs"],
{"H", 2435432, "1dfdsfdsfsdd"],
{NULL,}; {"1dfdsfdsfsdd",}.
};
void print(struct a *data)
{
int widths[3] = {0};
struct a *wrk;
size_t len;
for(wrk = data; wrk -> s; wrk )
{
if((len = strlen(wrk -> s)) > widths[0]) widths[0] = len。
if((len = strlen(wrk -> y)) > widths[2]) widths[2] =len;
if((len = snprintf(NULL, 0, "%d", wrk -> x)) > widths[1]) widths[1] = len;
}
for(wrk = data; wrk -> s; wrk )
{
printf("|%-*s | %*d | %*s |
", widths[0], wrk -> s , widths[1], wrk -> x, widths[2] , wrk -> y)。)
}
}
輸出:
| Hello | 1550738536 | 1|
| dfgsfdgdgdfgdf | 5 | 1fdsfsdfs !
| Hellodfds | 43534 | sdffs |
| H | 2435432 1dfdsfdsfsdd | |
uj5u.com熱心網友回復:
考慮到一個完成相同目標的假想的例子。
#include <stdio.h>/span>
#include <string.h>
struct ContrivedData {
char a[100] 。
char b[100]。
char c[100]。
};
int main(void) {
struct ContrivedData cd1 = {"Hello" /span>, "world", "! "}。
struct ContrivedData cd2 = {"foo"/span>, "bar", " baz"}。
struct ContrivedData cd[2];
cd[0] = cd1;
cd[1] = cd2。
int cd_len = sizeof(cd) / sizeof(*cd)。
int max_a_len = 0;
int max_b_len = 0;
int max_c_len = 0;
for (int i = 0; i < cd_len; i ) {
int a_len = strlen(cd[i].a)。
if (a_len > max_a_len) {
max_a_len = a_len。
}
int b_len = strlen(cd[i].b)。
if (b_len > max_b_len) {
max_b_len = b_len。
}
int c_len = strlen(cd[i].c)。
if (c_len > max_c_len) {
max_c_len = c_len。
}
}
for (int i = 0; i < cd_len; i ) {
printf("%-*s |%-*s |%-*s
",
max_a_len, cd[i].a,
max_b_len, cd[i].b,
max_c_len, cd[i].c)。
}
return 0。
}
在列印資料之前,我會遍歷陣列并計算每個欄位的最大寬度。根據資料的型別,你可能需要使用strlen以外的一些函式。
我得到的結果是:
% ./test2
Hello | world | !
foo | bar | baz
如果我稍微改變一下資料,你可以看到它仍然保持對齊。
% ./test2
Hello | world | !
foo | barbarbar | baz
轉載請註明出處,本文鏈接:https://www.uj5u.com/yidong/310460.html
標籤:
上一篇:安卓11存盤訪問和Java檔案庫
