【问题标题】:Entire file is not read in C (EOF occurs unexpectedly)未在 C 中读取整个文件(EOF 意外发生)
【发布时间】:2015-07-09 06:40:16
【问题描述】:

我正在尝试打印大约 4000 个字符的文件内容。 不知何故,程序只记录前 220 个字符并终止。

int main(void)
{
    char ch = ' ', file_name[25], payload[3904];
    FILE *fp;
    printf("Enter the name of file you wish to see\n");
    gets(file_name);
    fp = fopen(file_name, "r"); // read mode
    if (fp == NULL)
    {
        perror("Error while opening the file.\n");
        exit(EXIT_FAILURE);
    }

    printf("The contents of %s file are :\n", file_name);

    int gin = 0;
    while ((ch = fgetc(fp)!=EOF))
    {
        printf("%d) %x \n",gin, ch);
        payload[gin++] = ch;
    }
    printf("Also, value of gin is %d --->", gin);
    getchar();

    //...rest of the code
}

这里gin的值为220。

为了检查,我修改了while() 条件以运行文件中的确切字符数:

{
 //...

 while (gin<3904)
 {
    if ((ch = fgetc(fp)) == EOF) res++;//ADDED THIS TO COUNT NUMBER OF EOF's
    printf("%d) %x \n",gin, ch);
    payload[gin++] = ch;
    //printf(" %x \n", payload[(gin - 1)]);

    if (gin % 100 == 0)     
    {
        printf("Also, value of res is %d --->", res); getchar();
        getchar();
    }
 }

 //...rest of the code
}

gin 的值达到 3904,res(no. of EOF's) 的值是 3684,这意味着第一个 220 之后的每个字符都被读取为 EOF。程序在第一个 220 个字符之后开始读取 FF,即使它已被填充。

【问题讨论】:

  • 您想将c 设为int。看看fgetc() 返回什么类型。
  • gets() 很危险...改用fgets()
  • @sourav 它说:“fgets 的字符太少”
  • 哦,来吧,请查看手册页.....
  • 您调用fgetc 两次,结果第一个被丢弃。结果是第二个字符没有被计算或存储。

标签: c file-io


【解决方案1】:

我认为代码很好,除了您应该将ch 更改为int

fgetc() 返回

  • 如果成功,“读取为无符号字符的字符转换为int
  • 失败,EOF on end of file or error”

因此,首先,您必须将ch 更改为int,因为fgetc() 的某些返回值可能适合char

现在,在第二种情况下,您不会检查 fgetc()EOF 的返回值以检测任何错误。您只是获取返回值并尝试将这些值存储到数组中。实际上,当到达文件末尾时,就没有什么要读取的了,对同一个文件指针的所有进一步读取都会返回错误。

很可能是那些值。在您的情况下,220 之后完全是 valid

所以,对于你问题中的陈述,

(EOF 意外发生)

错了。它发生得很好,你忽略了它并遇到了,嗯,麻烦


注意:

  1. 在您的第一个 sn-p 中,您正在执行两个连续的 fgetc() 调用,基本上丢弃了第一个的结果,并使用第二个没有任何检查。
  2. 永远不要使用gets()。它存在缓冲区溢出问题。请始终使用fgets()

【讨论】:

  • 我更改了 ch 和 payload[] 的数据类型,但问题仍然存在。它打印正确的值直到 220,然后是“ffffffff”
  • @paneerchatpata 文件中只有 220 个有效字符,除此之外,所有读取都是错误的。
  • 我的文件显然包含超过 220 个字符。错误是否可能是因为使用 od fgetc?
【解决方案2】:

以下代码:

uses fgets() rather than the obsolete gets()
removed the newline from the user input
uses the proper size_t rather than int for indexing
is consistently indented
has modification to the printf statements to display size_t rather than int
compiles cleanly (which surprises me as payload is set but never used)

#include <stdio.h>
#include <stdlib.h>
#include <string.h>

int main(void)
{
    int ch = ' ';
    char file_name[25];
    char payload[3904];
    FILE *fp;

    printf("Enter the name of file you wish to see\n");
    fgets(file_name, sizeof(file_name), stdin);

    // remove trailing newline
    char *newline = strstr(file_name, "\n" );
    if (newline )  *newline = '\0';

    fp = fopen(file_name, "r"); // read mode
    if (fp == NULL)
    {
        perror("Error while opening the file.\n");
        exit(EXIT_FAILURE);
    }

    // implied else, fopen successful

    printf("The contents of %s file are :\n", file_name);

    size_t gin = 0;
    while ( ((ch = fgetc(fp)!=EOF)) && (sizeof(payload) > gin) )
    {
        printf("%ld) %x \n",gin, ch);
        payload[gin++] = ch;
    }

    printf("Also, value of gin is %ld --->", gin);
    getchar();

    //...rest of the code
    return(0);
}

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2021-03-15
    • 2023-03-06
    相关资源
    最近更新 更多