C 使用fgets从.txt文件读取和打印多行
我试图打印文本文件的前100个字符,包括新行,但是当我使用上面的代码时,它会出现一些奇怪的行为。首先,它只打印文本文件的最后一行,它本身不超过100个字符。另外,如果我在while循环中包含两个print语句,即C 使用fgets从.txt文件读取和打印多行,c,arrays,file,char,fgets,C,Arrays,File,Char,Fgets,我试图打印文本文件的前100个字符,包括新行,但是当我使用上面的代码时,它会出现一些奇怪的行为。首先,它只打印文本文件的最后一行,它本身不超过100个字符。另外,如果我在while循环中包含两个print语句,即 FILE *fp = fopen("story.txt", "r"); if(fp == NULL){ printf("\nError opening file.\nExiting program.\n"); exit(1); } char text[100]; wh
FILE *fp = fopen("story.txt", "r");
if(fp == NULL){
printf("\nError opening file.\nExiting program.\n");
exit(1);
}
char text[100];
while(fgets(text, 100, fp) != NULL){
printf("%s", text);
}
printf("\n");
fclose(fp);
}
它打印了超过125个字符的文本文件(数千个字符中的某个地方,这是一个大的文本文件),并且所述文本的内容是一个恒定流中文件中看似随机的一组片段,没有新行或任何内容
所以我想我的问题是,有没有办法使用fgets来打印文件中的文本,从顶部开始,并包含新行?我最终不得不使用它将文本文件转换为字符数组,这样我就可以基于该数组创建一个新的、修改过的字符数组,并将其打印到一个新的文本文件中。因此,如果有更好的方法实现最终目标,我们将不胜感激
编辑:在评论中经过一些讨论后,我意识到我使用的文本只是一大块文本,带有回车符,没有换行符。我想在这一点上,我的主要问题是如何将这个带回车符的文本文件转换成字符数组。如果目标是读取一个100个字符的文本文件,并消除回车符,只要记住
fgets(),您仍然可以使用fgets()
将在下一个换行之前(包括下一个换行),或直到读取的字符数小于指定的字符数为止
下面的代码读取一行文本,最多为BUFFER_SZ-1
个字符,增加内存分配以容纳新行文本,并将该行复制到分配的空间中,删除回车符和任何尾随换行符。请注意,重新分配的空间的地址首先存储在临时指针中realloc()
在发生分配错误时返回空指针,此步骤避免了潜在的内存泄漏
由于行在BUFFER_SZ-1
字符处断开,因此单词可能会跨行拆分,您可能需要开发额外的逻辑来处理此问题。在更大的块中进行重新分配会更有效,并且重新分配的频率会更低,而不是像这里所做的那样,每行重新分配一次。还请注意,以二进制模式打开文件以更紧密地解析行结尾可能很有用
while(fgets(text, 100, fp) != NULL){
printf("%s", text);
printf("%s", text);
它不会将一行复制到另一行的末尾。它只是重复使用您不断传递的缓冲区。如果要存储多行,请将它们复制到另一个缓冲区,并将它们连接起来。(请参阅:strcat)文本文件中的行有多长?我怀疑您的行长远远超过100个字符,因此大部分时间
text
中都没有换行符。您可以尝试添加fflush(stdout)调用printf()
后的code>似乎行少于100个字符,而正在打印的行的段少于100个字符。电流输出有很多非常奇怪的行为。例如,当我包含两个prinf语句并将终端的宽度调整为100多个时,结果只打印出文本文件的最后一行,以及文本末尾附近的一些额外的看似随机的单词。然而,当终端被调整到更小的尺寸时,它会打印出更多的文本。当只使用一个printf语句时,会发生类似的情况。您发布的代码看起来不错;我在一个文本文件上测试了它。编译后的后期工作代码和一个简短的文本示例将再现您观察到的行为。顺便说一句,行长由换行符决定,对于名为“story.txt”
的文件,我希望每个段落都有换行符,所以我希望行长超过100个字符。这不对吗?我在一个示例文本文件上测试了我的代码,其中所有的行肯定都不超过100个字符,它工作得非常好。我希望你对每一段的新行都是正确的,我一定错过了,因为我的文本编辑器显示文本时好像有新行一样(编辑:我刚在Vim中打开它,它没有显示新行,我不确定Gedit为什么没有显示相同的行)。要解决这个问题,我是否需要将大小从100增加到更大?
#include <stdio.h>
#include <stdlib.h>
#define BUFFER_SZ 100
int main(void)
{
FILE *fp = fopen("story.txt", "r");
if (fp == NULL) {
fprintf(stderr, "Unable to open file\n");
exit(EXIT_FAILURE);
}
char buffer[BUFFER_SZ];
char (*text)[sizeof buffer] = NULL;
char (*temp)[sizeof buffer] = NULL;
size_t numlines = 0;
while (fgets(buffer, sizeof buffer, fp) != NULL) {
++numlines;
/* Allocate space for next line */
temp = realloc(text, sizeof(*text) * numlines);
if (temp == NULL) {
fprintf(stderr, "Error in realloc()\n");
exit(EXIT_FAILURE);
}
text = temp;
/* Copy buffer to text, removing carriage returns and newlines */
char *c = buffer;
char *line = text[numlines-1];
while (*c != '\n' && *c != '\0') {
if (*c != '\r') {
*line++ = *c;
}
++c;
}
*c = '\0';
}
if (fclose(fp) != 0) {
fprintf(stderr, "Unable to close file\n");
}
for (size_t i = 0; i < numlines; i++) {
printf("%s\n", text[i]);
}
free(text);
return 0;
}
...
/* Copy buffer to text, converting carriage returns to newlines */
char *c = buffer;
char *line = text[numlines-1];
while (*c != '\n' && *c != '\0') {
if (*c == '\r') {
*line++ = '\n';
} else {
*line++ = *c;
}
++c;
}
*c = '\0';
}
if (fclose(fp) != 0) {
fprintf(stderr, "Unable to close file\n");
}
for (size_t i = 0; i < numlines; i++) {
printf("%s", text[i]);
}
...