【问题标题】:compiler says:cannot convert int to FILE*编译器说:无法将 int 转换为 FILE*
【发布时间】:2010-08-23 16:05:52
【问题描述】:

在归档时我卡在这里。while 循环的条件不起作用。编译器说无法将 int 转换为 FILE*。

while(pFile!=EOF);

我应该将 pFile 类型化为 int 吗?我试过了,但没有成功。提前致谢。 完整代码为:

int main()
{
    char ch;
    char name[20];
    FILE *pFile;
    int score;
    pFile=fopen("database.txt","r");
    if(pFile!=NULL)
    {

         while(pFile!=EOF);
        {
        fscanf(pFile,"%c",ch);
        }
    }
    else
    printf("Cant open the file.......");
        fclose(pFile);
        return 0;
}

【问题讨论】:

  • 建议:代替 printf("Can't open the file...." ),试试 perror(name); (在以前的某个时间点,您已经将“database.txt”复制到名称中,并且您已经处理了缓冲区大小问题。)这会将错误消息放在正确的流上,并且会提供更多信息。 perror 是你的朋友。
  • 在输出中它会打印错误但也会打印 ERROR=0,那是什么?

标签: c file


【解决方案1】:

首先,您确实想使用while (!feof(pFile))——永远!这样做几乎不可避免地会导致一个错误,即您从文件中读取的最后一个数据似乎被读取了两次。可以使其正常工作,但只能通过在循环中间添加另一个检查以在达到 EOF 时退出 - 在这种情况下,循环条件本身将永远不会被使用(即,另一个检查是实际上会完成退出循环的工作)。

您通常想要做的是在读取数据时检查 EOF。不同的函数以不同的方式表示 EOF。 fgets 通过返回 NULL 表示失败(包括 EOF)。大多数其他人(getc、fgetc 等)确实返回 EOF,因此您通常会得到如下结果:

int ch;   // Note, this should be int, NOT char

while (EOF != (ch=getc(pFile)))
    process(ch);

或:

char buffer[MAX_LINE_SIZE];

while (fgets(buffer, sizeof(buffer), pFile))
    process(buffer);

使用 scanf,检查成功有点复杂 - 它返回成功转换的数量,因此您需要确保与预期相符。例如:

while (1 == fscanf(fPfile, "%d", &input_number))
   process(input_number);

在这种情况下,我使用了1,因为我在格式字符串中指定了 1 次转换。但是,也有可能由于 EOF 以外的原因导致转换失败,因此如果失败,您将经常需要检查 feof(pFile)。如果它返回 false,请执行诸如读取该行的其余部分,在警告消息中将其显示给用户,然后继续读取文件的其余部分。

【讨论】:

    【解决方案2】:

    这取决于 pFile 和 EOF 的定义,但我假设 pFile 是一个 *FILE,而 EOF 来自 stdio.h。那我猜你应该做这样的事情:

    #include <stdlib.h>
    #include <stdio.h>
    
    #define FILENAME "file.txt"
    
    int main(void) {
        FILE *pFile;
        int ch;
    
        pFile = fopen(FILENAME,"r");
    
        if (pFile) {
            while ((ch = getc(pFile)) != EOF) {
                printf("Read one character: %c\n", ch);
            }
            close(pFile);
            return EXIT_SUCCESS;
        } else {
            printf("Unable to open file: '%s'\n", FILENAME);
            return EXIT_FAILURE;
        }
    }
    

    产生

    $ echo "abc" > file.txt
    $ /tmp/fileread 
    Read one character: a
    Read one character: b
    Read one character: c
    Read one character: 
    # last character being a linefeed
    

    【讨论】:

      【解决方案3】:

      假设pFile 是您的文件句柄,当您从文件中读取时,这不会改变。 EOF 由例如返回fgetc()。参见例如http://www.drpaulcarter.com/cs/common-c-errors.php#4.2 了解解决此问题的常用方法。

      【讨论】:

      • getchar() 仅适用于标准输入。您正在考虑 getc()/fgetc()。
      【解决方案4】:

      这是正确的方法:

      c = getc(pFile);
      while (c != EOF) {
          /* Echo the file to stdout */
          putchar(c);
          c = getc(pFile);
      }
      if (feof(pFile))
        puts("End of file was reached.");
      else if (ferror(pFile))
        puts("There was an error reading from the stream.");
      else
        /*NOTREACHED*/
        puts("getc() failed in a non-conforming way.");
      
      fclose(pFile);
      

      【讨论】:

      • feof? :O ...现在它说常量输出或范围。
      • 这应该只是while(!feof(pFile));
      • -1:这是一个典型的错误。如果你做while(!feof(pfile)){code},那么文件的最终值会被读取,feof的下一次检查会返回false,代码会再次执行(读取eof并用伪造的值做一些事情) ),并且在下一次检查条件时,循环将终止。你可能从不想写“while(!feof ...)”
      • -1 -- while (!feof(file)) 本质上总是错误的。在它后面加上分号更糟糕——这意味着没有任何东西可以改变条件,所以如果它执行,它将是一个无限循环。
      • @Jerry Coffin 谢谢你的课。我只是更正了作者写的内容,因为他稍后发布了其他部分代码
      【解决方案5】:

      pFile 是指向文件的指针。 EOF 通常定义为 -1,一个有符号整数。

      您应该做的是 fopen,确保 pFile != NULL,然后在文件句柄上调用某个函数,直到该函数返回 EOF。指针将(或者更确切地说,应该)永远不会是 EOF。但是作用于该指针的函数可能会返回 EOF。

      【讨论】:

        【解决方案6】:

        我猜你想在没有到达文件结尾时继续循环。在这种情况下,您正在寻找这个:

        while (!feof(pFile))
        {
            ...
        }
        

        也就是说,这仍然不完全正确。 feof 只会在尝试读取超出文件末尾时返回 true。这意味着feof 可以返回false,但没有更多数据可供读取。你真的应该尝试你的操作,如果失败,只检查文件结尾:

        char buffer[SIZE];
        while (fgets(buffer, sizeof(buffer), pFile))
        {
            ...
        }
        if (!feof(pFile))
        {
            // fgets failed for some reason *other* then end-of-file
        }
        

        【讨论】:

        • 小心!如果您的循环内容是例如fgets(line, sizeof(line), fp); fputs(line, stdout);,这将无法正常工作。
        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2020-04-01
        • 2014-05-28
        • 2016-03-15
        • 1970-01-01
        相关资源
        最近更新 更多