【问题标题】:Unknown Logical Error Using the getc() Function in C在 C 中使用 getc() 函数的未知逻辑错误
【发布时间】:2012-07-07 22:17:39
【问题描述】:

我正在尝试使用 getc() 函数将一个文件的内容复制到另一个文件中。但是我犯了一个未知的逻辑错误,因为以下程序的输出是一堆垃圾。

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

int main()
{
    FILE *f; 
    FILE *write;
    f = fopen("nums.csv","r");
    write = fopen("numsWrite.dat","w");

    char tempChar;

    int i;
    for(i = 0; (tempChar = getc(f)) != EOF; i++)
    {
        tempChar = getc(f);
        fprintf(write,"%c",tempChar);
    }
    fprintf(write,"\n");

    fclose(f);
    fclose(write);

    return 0;
}

nums.csv 的内容是:

1256,2548,35151,15,56,38

程序返回:

2624,55,55,8

【问题讨论】:

  • 请注意,这只适用于文本文件。在某些平台上,这会损坏二进制文件。

标签: c file-io getc


【解决方案1】:

您的代码有几个问题。

int main() 应该是int main(void);这是一个小问题,几乎肯定不会伤害任何东西,但后者更正确。

您不检查fopen() 调用是否成功。

您正在使用i 来计算您阅读的字符数,但您从不使用它的值做任何事情。

getc() 函数返回int 类型的结果,因此您应该绝对tempChar 设为int。这样做的原因是它可以返回一个有效的字符值(将适合char 对象)EOF,通常是-1。通过将getc() 的结果存储在char 对象中,您将永远看不到EOF(如果纯char 未签名),或者您将无法将EOF 与有效输入区分开来字符。

在对 Razvan 的回答发表评论时,您说您将测试更改为 tempChar != EOF。除了我上面解释的问题之外,在循环的第一次迭代中tempChar 还没有被初始化,比较的结果是不可预测的。

使用getc() 编写输入循环的常规方法是:

int c;
while ((c = getc(f)) != EOF) {
    /* do something with c */
}

就风格而言,write 对于FILE* 来说并不是一个很好的名字。一方面,有一个同名的函数(由 POSIX 定义,而不是由 C 定义,但它仍然可能令人困惑)。您可以改为将FILE* 对象称为inout

【讨论】:

    【解决方案2】:

    您调用 getc 两次:一次在 for 条件中,一次在 for 正文中。删除这一行: tempChar = getc(f);然后再试一次。

    【讨论】:

    • 将“(tempChar = getc(f)) != EOF”更改为“tempChar != EOF”。现在可以正常工作了。
    • 也可以,但是按照我说的标准方法。
    • @mysticxhobo:纯属巧合;看看我的答案(一旦我写完)。
    • @mysticxhobo 如果你只在循环中调用getc(),你会在最后尝试fwriteEOF。将getc() 保持在循环条件中。
    • @KeithThompson:当我说这种巧合很可能是幸福的时候,我说得对吗:(2^(8*sizeof(char)) - 1)/(2^( 8*sizeof(char))) :)
    猜你喜欢
    • 2012-01-03
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2015-06-01
    • 1970-01-01
    • 1970-01-01
    • 2018-03-12
    • 1970-01-01
    相关资源
    最近更新 更多