1

我写了以下程序:

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)中,我们不能保证!=首先评估的左侧部分,因此结果不正确。这是正确的解释吗?

4

2 回答 2

4

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

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

应该:

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

因为运算符的优先级 !=大于=条件表达式c=fgetc(f1)!=EOF中的运算符,所以第一个返回的结果是将 fromfgetc() 与 EOF(0 或 1)的值进行比较,并将其分配给c。(这意味着简单c=fgetc(f1)!=EOF的表达式等同于c=(fgetc(f1)!=EOF),这不是你需要的。)

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

但是您还有第二件事要改进,即c变量必须int不是 char)才能保持 EOF 值。

一个很好的阅读:EOF的定义以及如何有效地使用它

于 2013-07-18T04:57:04.307 回答
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
于 2013-07-18T05:07:53.083 回答