如何在C程序中读取文本文件的最后一行?

发布于 2025-02-01 12:06:21 字数 1409 浏览 2 评论 0原文

我正在尝试研究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 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(1

为你鎻心 2025-02-08 12:06:21

比较这两个程序,使用feof()一个(MIS),一个根本不使用它。第一个与问题中的代码紧密相对应 - 它忽略了从fgets()忽略其损害的返回值。第二个仅从fgets()中测试返回值;它无需使用feof()

eof53.c

#include <stdio.H>

int main(void)
{
    char buffer[256];

    fgets(buffer, sizeof(buffer), stdin);
    while (!feof(stdin))
    {
        printf("[%s]\n", buffer);
        fgets(buffer, sizeof(buffer), stdin);
    }
    return 0;
}

eof71.c

#include <stdio.H>

int main(void)
{
    char buffer[256];

    while (fgets(buffer, sizeof(buffer), stdin) != NULL)
        printf("[%s]\n", buffer);
    return 0;
}

给定数据文件abc包含3个字节 - 0x41('a'a'),, 0x42('b'),0x43('c'),没有newline,我得到以下结果:

$ eof53 < abc
$ eof71 < abc
[ABC]
$

这是在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 from fgets() to its detriment. The second only tests the return value from fgets(); it has no need to use feof().

eof53.c

#include <stdio.H>

int main(void)
{
    char buffer[256];

    fgets(buffer, sizeof(buffer), stdin);
    while (!feof(stdin))
    {
        printf("[%s]\n", buffer);
        fgets(buffer, sizeof(buffer), stdin);
    }
    return 0;
}

eof71.c

#include <stdio.H>

int main(void)
{
    char buffer[256];

    while (fgets(buffer, sizeof(buffer), stdin) != NULL)
        printf("[%s]\n", buffer);
    return 0;
}

Given a data file abc containing 3 bytes — 0x41 ('A'), 0x42 ('B'), 0x43 ('C') and no newline, I get the following results:

$ eof53 < abc
$ eof71 < abc
[ABC]
$

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 though fgets() did return a string (but not a line) of data.

As explained in the canonical Q&A while (!feof(file)) is always wrong!, using feof() rather than testing the return value from the I/O functions leads to bad results.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文