从C中的文件中逐字符读取字符

时间:2013-07-18 04:53:03

标签: c file-io

我写了以下程序:

int main(){
    char str[500],c;
    FILE *f1=fopen("input.txt","r");
    FILE *f2=fopen("output.txt","w");


    while(c=fgetc(f1)!=EOF)
    fputc(toupper(c),f2);


    fclose(f1);
}

虽然我没有得到理想的结果。 我用do while循环重写了代码。

int main(){
  char str[500];
  FILE *f1=fopen("input.txt","r");
  FILE *f2=fopen("output.txt","w");
  char c;

  do
  {
    fputc(toupper(c),f2);
    c=fgetc(f1);
  }while(c!=EOF);
}

我发现第一个代码失败的原因是因为在while循环中 while(c=fgetc(f1)!=EOF),我们无法保证首先评估!=的左侧部分,因此结果不合适。这是正确的解释吗?

2 个答案:

答案 0 :(得分:4)

是的,你是对的;在您的第一个代码中,您的while循环被错误地写入:

while(c=fgetc(f1)!=EOF)

应该是:

while((c=fgetc(f1))!=EOF)
//    ^           ^   added parenthesis

由于条件表达式!=中的precedence of operator =大于c=fgetc(f1)!=EOF运算符,因此第一个返回了将fgetc()的值与EOF进行比较的结果(0或1)并将其分配给c。 (这意味着简单地c=fgetc(f1)!=EOF表达式等同于c=(fgetc(f1)!=EOF),这不是您所需要的。)

您需要()覆盖我建议的优先级。

但是你需要改进的第二件事是c变量必须成为int char)持有EOF值。

非常好阅读:Definition of EOF and how to use it effectively

答案 1 :(得分:1)

我将添加一些为什么c应为int,而不是char。假设你写了

#include <stdio.h>
#include <ctype.h>
#include <locale.h>

int main(){
    setlocale(LC_ALL,"");
    FILE *f1=fopen("input.txt","r");
    FILE *f2=fopen("output.txt","w");
    char c;

    while(EOF != (c=fgetc(f1))){
        if(isalpha(c)) c = toupper(c);
        fputc(c,f2);
    }
return 0;
}

您的input.txt

some text
Некоторый текст
Ъ - on this letter program will stop

在KOI8-R中,符号Ъ的代码为255 == -1(当您使用char时)。 这就是为什么在使用char代替int的情况下,只会为output.txt提供该文字:

SOME TEXT
НЕКОТОРЫЙ ТЕКСТ

对于带括号的非工作代码:c=fgetc(f1)!=EOF可以被编译器表示为c = (fgetc(f1)!=EOF),这就是为什么最好总是添加括号。

我建议您在编译应用程序时使用标记-Wall -Werror。在这种情况下,“忘记”括号会给你一个错误:

11.c: In function 'main':
11.c:9:2: error: suggest parentheses around assignment used as truth value [-Werror=parentheses]
cc1: all warnings being treated as errors