gpt4 book ai didi

c - 使用 fgetc() 逐行读取 c 文件

转载 作者:太空狗 更新时间:2023-10-29 17:18:08 24 4
gpt4 key购买 nike

我是这样做的,但我不确定这是首选的习惯用法:

FILE *fp = fopen(argv[0], "r");
// handle fopen() returning NULL

while (!feof(fp)) {
char buffer[80]; // statically allocated, may replace this later with some more sophisticated approach
int num_chars = 0;

for (int ch = fgetc(fp); ch != EOF && ch != '\n'; ch = fgetc()) {
buffer[num_chars++] = ch;
}

// null-terminate the string
buffer[num_chars] = '\0';

printf("%s\n", buffer);
}

这样可以吗,有什么改进的建议吗?

最佳答案

如果你不打算使用fgets()(可能是因为你想删除换行符,或者你想处理"\r""\n""\r\n" 行结尾,或者您想知道读取了多少个字符),您可以将其用作骨架函数:

int get_line(FILE *fp, char *buffer, size_t buflen)
{
char *end = buffer + buflen - 1; /* Allow space for null terminator */
char *dst = buffer;
int c;
while ((c = getc(fp)) != EOF && c != '\n' && dst < end)
*dst++ = c;
*dst = '\0';
return((c == EOF && dst == buffer) ? EOF : dst - buffer);
}

它只识别换行符作为行尾;它删除了换行符。它不会溢出缓冲区;它不会丢弃多余的字符,因此如果要求读取很长的一行,它将以 block 的形式读取该行;它返回读取的字符数。如果您需要区分溢出和恰好是缓冲区长度的行 - 1,那么您可能需要保留换行符 - 并相应地更改代码:

int get_line(FILE *fp, char *buffer, size_t buflen)
{
char *end = buffer + buflen - 1; /* Allow space for null terminator */
char *dst = buffer;
int c;
while ((c = getc(fp)) != EOF && dst < end)
{
if ((*dst++ = c) == '\n')
break;
}
*dst = '\0';
return((c == EOF && dst == buffer) ? EOF : dst - buffer);
}

对此有无穷无尽的小变体,例如,如果必须截断该行,则丢弃任何多余的字符。如果您想处理 DOS、(旧的)Mac 或 Unix 行尾,请从 "The Practice of Programming" 的 CSV 代码中借用一片叶子。 Kernighan & Pike(一本优秀的书)并使用:

static int endofline(FILE *ifp, int c)
{
int eol = (c == '\r' || c == '\n');
if (c == '\r')
{
c = getc(ifp);
if (c != '\n' && c != EOF)
ungetc(c, ifp);
}
return(eol);
}

然后你可以用它来代替 c != '\n' 测试:

int get_line(FILE *fp, char *buffer, size_t buflen)
{
char *end = buffer + buflen - 1; /* Allow space for null terminator */
char *dst = buffer;
int c;
while ((c = getc(fp)) != EOF && !endofline(fp, c) && dst < end)
*dst++ = c;
*dst = '\0';
return((c == EOF && dst == buffer) ? EOF : dst - buffer);
}

另一种处理整个过程的方法是使用 fread()fwrite():

void copy_file(FILE *in, FILE *out)
{
char buffer[4096];
size_t nbytes;
while ((nbytes = fread(buffer, sizeof(char), sizeof(buffer), in)) != 0)
{
if (fwrite(buffer, sizeof(char), nbytes, out) != nbytes)
err_error("Failed to write %zu bytes\n", nbytes);
}
}

在上下文中,您将打开文件并检查其有效性,然后调用:

copy_file(fp, stdout);

关于c - 使用 fgetc() 逐行读取 c 文件,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/4293475/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com