简体   繁体   English

从C中的文件逐字符读取

[英]Reading character by character from a file in C

I wrote the following program : 我写了以下程序:

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);
}

I was not getting the desired result though. 我没有得到想要的结果。 I rewrote the code using a do while loop. 我使用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);
}

I figured out that the reason the first code fails is because in the while loop while(c=fgetc(f1)!=EOF) , we cannot guarantee that the left part of != is evaluated first and hence the results are not proper. 我发现第一个代码失败的原因是因为在while循环while(c=fgetc(f1)!=EOF) ,我们不能保证!=的左半部分首先被求值,因此结果不正确。 Is this correct the explanation? 这是正确的解释吗?

Yes you are correct; 是的,你是对的; in your first code your while loop is written wrongly: 在您的第一个代码中,您的while循环写错了:

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

Should be: 应该:

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

Because the precedence of operator != is greater than = operator in conditional expression c=fgetc(f1)!=EOF , the first returned the result of comparing the value from fgetc() with EOF (either 0 or 1) and assigned that to c . 由于条件表达式c=fgetc(f1)!=EOF 中运算符 !=优先级大于=运算符,因此第一个运算符返回将fgetc()的值与EOF(0或1)进行比较的结果,并将其分配给c (That means simply c=fgetc(f1)!=EOF expression is equivalent to c=(fgetc(f1)!=EOF) and this is not what you need.) (这意味着简单地c=fgetc(f1)!=EOF表达式等效于c=(fgetc(f1)!=EOF) ,这不是您所需要的。)

You need () to overwrite precedence as I suggested. 您需要()覆盖我建议的优先级。

But you have second thing to improve that is c variable must be an int ( not char ) in order to hold an EOF-value. 但是您还有第二点要改进的地方,就是c变量必须int而不是 char )才能保留EOF值。

A very good Read: Definition of EOF and how to use it effectively 很好的阅读: EOF的定义以及如何有效使用它

I will add a little why c should be int , not char . 我将补充一点,为什么c应该是int而不是char Suppose you write 假设你写

#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;
}

And your input.txt is 而您的input.txt

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

in KOI8-R symbol Ъ have code 255 == -1 (when you use char ). 在KOI8-R符号Ъ具有代码255 == -1(当使用char )。 That's why in case of using char instead of int will give your output.txt with only that text: 这就是为什么在使用char而不是int情况下将只为该文本提供output.txt

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

As for non-working code with parentheses: c=fgetc(f1)!=EOF could be denote by compiler as c = (fgetc(f1)!=EOF) , that's why it's better always to add parentheses. 至于带有括号的非工作代码: c=fgetc(f1)!=EOF可以由编译器表示为c = (fgetc(f1)!=EOF) ,这就是为什么总是加括号的原因。

I recommend you to use flags -Wall -Werror when compiling your applications. 我建议您在编译应用程序时使用标志-Wall -Werror In that case "forgetting" of parentheses would give you an error: 在这种情况下,“忘记”括号会给您一个错误:

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

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM