如何在 C 编程中使用 fgets 编写返回文本文件所有内容的函数?
Posted
技术标签:
【中文标题】如何在 C 编程中使用 fgets 编写返回文本文件所有内容的函数?【英文标题】:How can I write a function That returns all the content of a text file using fgets in C programming? 【发布时间】:2022-01-14 06:50:41 【问题描述】:我想编写一个函数 char* lire(FILE* f),它应该读取文本文件并返回其内容,我想返回它而不仅仅是读取它并显示它。 我想使用 fgets。
此代码有效,但不是我想要的
char *lire(FILE *f)
char *content;
content = (char*)malloc((strlen(content) + 1) * sizeof(char));
while (fgets(content,120000, f) )
printf("%s", content);
return 0;
相反,我尝试了返回文本文件,但它只显示了我的文本文件的第一行
char *lire(FILE *f)
char *content;
content = (char*)malloc((strlen(content) + 1) * sizeof(char));
while (fgets(content,120000, f) )
return content;
【问题讨论】:
fgets
只读取一行文本。除非文件包含一行文本,否则无法使用 fgets
读取整个文件。你可能需要fread
。
顺便说一句:当content
是一个未初始化的指针时,你认为strlen(content)
是什么?
我不明白为什么可以使用它来读取第一个代码中的多行,而第二个代码中却没有。谢谢。
这两个代码 sn-ps 都存在多个问题。先处理我的第二条评论。这很重要,相信我。
在您的第一个代码中,您打印该行,然后在循环中进行另一轮。这种情况接二连三地发生。 fgets
不超过那一行。在第二个代码中,您只是退出工作并在第一行之后返回。
【参考方案1】:
有几种方法可以使用fgets()
将整个文本文件读入单个字符串,但它们都将迭代使用fgets()
。您可以尝试预先确定文件的大小,然后分配足够的空间并读入该空间。这适用于您可以在文件中查找的磁盘文件;如果输入来自管道、终端、套接字或大多数其他不是磁盘文件的东西,它就不起作用。还有一个TOCTOU(检查时间,使用时间)问题;当您的代码读取文件时,文件大小可能会发生变化。
或者,您可以简单地读入分配的空间,在需要时重新分配更多空间。这适用于任何类型的输入文件。
使用fgets()
意味着文件不能有效地包含空字节。那是因为fgets()
没有报告它读取了多少数据,所以你必须使用strlen()
来找出数据的长度,而strlen()
在它遇到的第一个空字节处停止。
使用增量分配,您可能会得到如下代码:
/* SO 7028-9928 */
/* Slurp a file using fgets() */
/* #include "slurp.h" */
/* SOF - slurp.h */
#include <stdio.h>
extern char *slurp_file(FILE *fp);
/* EOF - slurp.h */
#include <stdlib.h>
#include <string.h>
#define INIT_ALLOC 1024
#define MIN_SPACE 256
#define MAX_EXCESS 256
char *slurp_file(FILE *fp)
size_t offset = 0;
size_t bufsiz = INIT_ALLOC;
char *buffer = malloc(bufsiz);
if (buffer == NULL)
return NULL;
while (fgets(buffer + offset, bufsiz - offset, fp) != NULL)
/* Assumes data does not contain null bytes */
/* Generic problem using fgets() */
size_t newlen = strlen(buffer + offset);
offset += newlen;
if (bufsiz - offset < MIN_SPACE)
size_t new_size = bufsiz * 2;
char *new_data = realloc(buffer, new_size);
if (new_data == NULL)
free(buffer);
return NULL;
bufsiz = new_size;
buffer = new_data;
if (bufsiz - offset > MAX_EXCESS)
buffer = realloc(buffer, offset + 1);
return buffer;
int main(void)
char *data;
if ((data = slurp_file(stdin)) != NULL)
printf("Size: %zu\n", strlen(data));
printf("Data: [[%s]]\n", data);
free(data);
return 0;
当程序在自己的源代码上运行时,它会产生如下输出:
Size: 1362
Data: [[/* SO 7028-9928 */
/* Slurp a file using fgets() */
…
return 0;
]]
另一种方法是使用fread()
而不是fgets()
— 这可以处理二进制数据,但您需要修改函数接口以报告数据的长度和指向数据开头的指针。
【讨论】:
以上是关于如何在 C 编程中使用 fgets 编写返回文本文件所有内容的函数?的主要内容,如果未能解决你的问题,请参考以下文章
C 语言文件操作 ( 按照文本行的方式读写文件 | fgets 函数 | fputs 函数 )