如何在C程序中读取文本文件的最后一行?
我正在尝试研究C语言,基本上我想做的就是阅读文件并将其放入我创建的结构中,然后稍后我将使用结构进行其他操作,但是我想通过第一部分。假设我有一个称为captains.txt的文本文件,内容为:(请
picard 95
janeway 90
pike 15
注意,最后一行只是“派克15'”),
所以我创建了一个类似的程序:
#include <stdio.h>
#include <stdlib.h> //for exit()
#include <string.h>
#include <ctype.h>
struct captain
{
char capName[10];
int number;
};
typedef struct captain captain;
int main()
{
FILE* file = fopen("captain.txt","r");
if (file == NULL)
{
printf("\nerror opening file");
exit(1);
}
else{
printf("\nfile is opened");
}
char buffer[50];
fgets(buffer,50,file);
while (!feof(file))
{
captain c;
sscanf(buffer, "%s %d", &c.capName, &c.number);
printf("\nc captain is: %s %d", c.capName, c.number);
fgets(buffer,50,file);
}
fclose(file);
return 0;
}
我的控制台上的输出是
file is opened
c captain is: picard 95
c captain is: janeway 90
Process returned 0 (0x0) execution time : 0.006 s
Press any key to continue.
我缺少派克队长的pike。在太空中...几乎从字面上看,因为当我在文本文件中添加新行时,它会像这样:(
picard 95
janeway 90
pike 15
请注意“ Pike 15”之后的NewLine)
,我的输出变得正确。因此,我知道我的程序在文件末尾没有说明缺乏新线...那么如何解决这个问题?
I'm trying to study the C language and basically what I want to do is read a file and put it into a struct I created, and then later I'll be doing other things with the struct, but I want to get through the first part first. Let's say that I have a text file called captains.txt and the contents are:
picard 95
janeway 90
pike 15
(note that the last line is just 'pike 15')
So I created a program that's like this:
#include <stdio.h>
#include <stdlib.h> //for exit()
#include <string.h>
#include <ctype.h>
struct captain
{
char capName[10];
int number;
};
typedef struct captain captain;
int main()
{
FILE* file = fopen("captain.txt","r");
if (file == NULL)
{
printf("\nerror opening file");
exit(1);
}
else{
printf("\nfile is opened");
}
char buffer[50];
fgets(buffer,50,file);
while (!feof(file))
{
captain c;
sscanf(buffer, "%s %d", &c.capName, &c.number);
printf("\nc captain is: %s %d", c.capName, c.number);
fgets(buffer,50,file);
}
fclose(file);
return 0;
}
The output on my console is
file is opened
c captain is: picard 95
c captain is: janeway 90
Process returned 0 (0x0) execution time : 0.006 s
Press any key to continue.
Hence Captain Pike is missing in space... almost literally because when I add a new line to the text file that it becomes like this:
picard 95
janeway 90
pike 15
(note the newline after 'pike 15')
Then my output becomes correct. So I know that my program doesn't account for the lack of a newline at the end of the file... so how do I solve this?
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(1)
比较这两个程序,使用
feof()
一个(MIS),一个根本不使用它。第一个与问题中的代码紧密相对应 - 它忽略了从fgets()
忽略其损害的返回值。第二个仅从fgets()
中测试返回值;它无需使用feof()
。eof53.c
eof71.c
给定数据文件
abc
包含3个字节 - 0x41('a'a'
),, 0x42('b'
),0x43('c'
),没有newline,我得到以下结果:这是在Macos Big Sur 11.6.6上测试的。
请注意,
fgets()
在阅读(仅)不完整的行时不会报告EOF(通过返回null指针),但是从经验上,feof()
确实报告EOF - &nbsp ;正确地,由于文件输入已经结束,即使fgets()
确实返回了字符串(但不是一行)数据。如规范Q&amp; a
while while(!feof(file))
始终是错误的!,使用feof()
而不是从I/O功能中测试返回值会导致不良结果。Compare these two programs, one (mis)using
feof()
and one not using it at all. The first corresponds closely to the code in the question — it ignores the return value fromfgets()
to its detriment. The second only tests the return value fromfgets()
; it has no need to usefeof()
.eof53.c
eof71.c
Given a data file
abc
containing 3 bytes — 0x41 ('A'
), 0x42 ('B'
), 0x43 ('C'
) and no newline, I get the following results:This was tested on MacOS Big Sur 11.6.6.
Note that
fgets()
does not report EOF (by returning a null pointer) when reading the (only) incomplete line, but empirically,feof()
does report EOF — correctly, since the file input has ended, even thoughfgets()
did return a string (but not a line) of data.As explained in the canonical Q&A
while (!feof(file))
is always wrong!, usingfeof()
rather than testing the return value from the I/O functions leads to bad results.