【发布时间】:2021-11-08 07:52:33
【问题描述】:
我已经用 C 编写了这个程序,它读取一个文件并将其打印到一个与垂直条对齐的表格中,包括标题和足迹。该文件始终有 3 列,但行数不同。这些列的字符数量会有所不同。我遇到的问题是,我读入的第一个文件完全对齐,但是当我读入其他所有列中尺寸增加的文件时,它没有对齐。有没有办法让它自动对齐,还是我每次都必须手动执行?
代码:
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
// constant to store the maximum size of the records that can be read from the file
enum
{
// update MAX_SIZE to if the number of rows is more than 1000
MAX_SIZE = 1024
};
// structure to store a record from the file
typedef struct
{
char define[20];
char octal[26];
char description[1000];
} Record;
// string to store the header of the table
char header1[20], header2[20], header3[20];
// function to read the file and return the maximum length of the descriptions read from the file
int readFile(Record rec[], int *size)
{
// open a file for input
FILE *fp = fopen("input2.txt", "r");
// check if the file opened successfully
if (fp == NULL)
{
printf("File could not be opened!");
exit(1);
}
int i = 0;
int maxLength=0;
// read the file
// first we read the header of each column from the file
fscanf(fp, "%s %s %s\n", header1, header2, header3);
// now we read each record from the file
while (fscanf(fp, "%19s ", rec[i].define) == 1)
{
fscanf(fp, "%10s '%[^']'", rec[i].octal, rec[i].description);
// find the length of the description and update the 'maxLength'
if (strlen(rec[i].description) > maxLength)
{
maxLength = strlen(rec[i].description);
}
// increment the value of i
i++;
}
// close the input file
fclose(fp);
// update the number of records read from the file
*size = i;
return maxLength;
}
void printTable(Record rec[], int size, int WIDTH)
{
char p='|';
// print the header of the table
for (int i = 0; i < 22 + WIDTH; i++)
printf("-");
printf("\n| %-7s %c %5s %c %-*s %c\n", header1, p, header2, p, WIDTH, header3,p);
for (int i = 0; i < 22 + WIDTH; i++)
printf("-");
printf("\n");
// print the table data
for (int i = 0; i < size; i++)
printf("| %-7s | %5s | %-*s |\n", rec[i].define, rec[i].octal, WIDTH, rec[i].description);
// print the footer
for (int i = 0; i < 22 + WIDTH; i++)
printf("-");
printf("\n");
}
// driver function
int main()
{
// create an array of recors of MAX_SIZE
Record recs[MAX_SIZE];
// initialize size of recs to zero
int size = 0;
// call readFile() function to read data from the file and update the size of recs
int WIDTH = readFile(recs, &size);
// call printTable() function to print the table in a well-formatted manner
printTable(recs, size, WIDTH);
return 0;
}
文件:
#define octal description
O_APPEND 02000 'The file is opened in append mode.'
O_ASYNC 020000 'Enable signal-driven I/O.'
O_CLOEXEC 02000000 'Enable the close-on-exec flag for the new file descriptor.'
O_CREAT 0100 'If pathname does not exist, create it as a regular file.'
O_DIRECT 040000 'Try to minimize cache effects of the I/O to and from this file.'
O_DIRECTORY 0200000 'If pathname is not a directory, cause the open to fail.'
O_DSYNC 010000 'Write operations will complete according to the requirements of synchronized I/O data integrity completion.'
O_EXCL 0200 'Ensure that this call creates the file.'
O_LARGEFILE 0 'Allow files whose sizes cannot be represented in an off_t to be opened.'
O_NOATIME 01000000 'Do not update the file last access time (st_atime in the inode) when the file is read(2).'
O_NOCTTY 0400 'If pathname refers to a terminal device it will not become the processs controlling terminal.'
O_NOFOLLOW 0400000 'If pathname is a symbolic link, then the open fails, with the error ELOOP.'
O_NONBLOCK 04000 'When possible, the file is opened in nonblocking mode.'
O_PATH 010000000 'Obtain a file descriptor that can be used perform operations that act purely at the file descriptor level.'
O_SYNC 04010000 'Write operations will complete according to the requirements of synchronized I/O file integrity completion.'
O_TMPFILE 020200000 'Create an unnamed temporary regular file.'
O_TRUNC 01000 'If the file already exists and is a regular file it will be truncated to length 0.'
当前正在打印的内容:
---------------------------------------------------------------------------------------------------------------------------------
| #define | octal | description |
---------------------------------------------------------------------------------------------------------------------------------
| O_APPEND | 02000 | The file is opened in append mode. |
| O_ASYNC | 020000 | Enable signal-driven I/O. |
| O_CLOEXEC | 02000000 | Enable the close-on-exec flag for the new file descriptor. |
| O_CREAT | 0100 | If pathname does not exist, create it as a regular file. |
| O_DIRECT | 040000 | Try to minimize cache effects of the I/O to and from this file. |
| O_DIRECTORY | 0200000 | If pathname is not a directory, cause the open to fail. |
| O_DSYNC | 010000 | Write operations will complete according to the requirements of synchronized I/O data integrity completion. |
| O_EXCL | 0200 | Ensure that this call creates the file. |
| O_LARGEFILE | 0 | Allow files whose sizes cannot be represented in an off_t to be opened. |
| O_NOATIME | 01000000 | Do not update the file last access time (st_atime in the inode) when the file is read(2). |
| O_NOCTTY | 0400 | If pathname refers to a terminal device it will not become the processs controlling terminal. |
| O_NOFOLLOW | 0400000 | If pathname is a symbolic link, then the open fails, with the error ELOOP. |
| O_NONBLOCK | 04000 | When possible, the file is opened in nonblocking mode. |
| O_PATH | 010000000 | Obtain a file descriptor that can be used perform operations that act purely at the file descriptor level. |
| O_SYNC | 04010000 | Write operations will complete according to the requirements of synchronized I/O file integrity completion. |
| O_TMPFILE | 020200000 | Create an unnamed temporary regular file. |
| O_TRUNC | 01000 | If the file already exists and is a regular file it will be truncated to length 0. |
---------------------------------------------------------------------------------------------------------------------------------
它应该是什么样子:
-----------------------------------------------------------------------------------------------------------------------------------------
| #define | octal | description |
-----------------------------------------------------------------------------------------------------------------------------------------
| O_APPEND | 02000 | The file is opened in append mode. |
| O_ASYNC | 020000 | Enable signal-driven I/O. |
| O_CLOEXEC | 02000000 | Enable the close-on-exec flag for the new file descriptor. |
| O_CREAT | 0100 | If pathname does not exist, create it as a regular file. |
| O_DIRECT | 040000 | Try to minimize cache effects of the I/O to and from this file. |
| O_DIRECTORY | 0200000 | If pathname is not a directory, cause the open to fail. |
| O_DSYNC | 010000 | Write operations will complete according to the requirements of synchronized I/O data integrity completion. |
| O_EXCL | 0200 | Ensure that this call creates the file. |
| O_LARGEFILE | 0 | Allow files whose sizes cannot be represented in an off_t to be opened. |
| O_NOATIME | 01000000 | Do not update the file last access time (st_atime in the inode) when the file is read(2). |
| O_NOCTTY | 0400 | If pathname refers to a terminal device it will not become the processs controlling terminal. |
| O_NOFOLLOW | 0400000 | If pathname is a symbolic link, then the open fails, with the error ELOOP. |
| O_NONBLOCK | 04000 | When possible, the file is opened in nonblocking mode. |
| O_PATH | 010000000 | Obtain a file descriptor that can be used perform operations that act purely at the file descriptor level. |
| O_SYNC | 04010000 | Write operations will complete according to the requirements of synchronized I/O file integrity completion. |
| O_TMPFILE | 020200000 | Create an unnamed temporary regular file. |
| O_TRUNC | 01000 | If the file already exists and is a regular file it will be truncated to length 0. |
-----------------------------------------------------------------------------------------------------------------------------------------
【问题讨论】:
-
"| %-12s | %9s | %-*s |\n"
-
我知道如何手动完成。问题是当尺寸发生变化时,我需要它来自动格式化。
-
听起来您需要在开始打印之前遍历表格的内容并计算每列的最大宽度。
-
如果我要找到这个,我怎么能把那个数字放在 %s 前面?
-
您已经有代码可以在读取描述字段时找到其最大长度,以及适应该字段打印的代码。将其扩展到其他两个领域有什么问题?它们可以用相同的方式测量和格式化。宽度不能作为单个数字从
readFile返回,但有多种选择。