Napisałem następujący 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);
}
Jednak nie uzyskałem pożądanego rezultatu. Przepisałem kod za pomocą pętli 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);
}
Doszedłem do wniosku, że przyczyną niepowodzenia pierwszego kodu jest pętla while
while(c=fgetc(f1)!=EOF)
, nie możemy zagwarantować, że lewa część !=
jest oceniany jako pierwszy, a zatem wyniki są nieprawidłowe. Czy to poprawne wyjaśnienie?
Odpowiedzi:
4 dla odpowiedzi № 1Tak, masz rację; w pierwszym kodzie twoja pętla while jest zapisana niepoprawnie:
while(c=fgetc(f1)!=EOF)
Powinno być:
while((c=fgetc(f1))!=EOF)
// ^ ^ added parenthesis
Ponieważ pierwszeństwo operatora !=
jest większy niż =
operator w wyrażeniu warunkowym c=fgetc(f1)!=EOF
, pierwszy zwrócił wynik porównania wartości z fgetc()
z EOF (0 lub 1) i przypisany do c
. (To oznacza po prostu c=fgetc(f1)!=EOF
wyrażenie jest równoważne c=(fgetc(f1)!=EOF)
a nie tego potrzebujesz).
Potrzebujesz ()
nadpisać pierwszeństwo, jak zasugerowałem.
Ale musisz jeszcze coś poprawić c
zmienna musi fasola int
(nie char
) w celu utrzymania wartości EOF.
Bardzo dobry Przeczytaj: Definicja EOF i sposób jego efektywnego wykorzystania
1 dla odpowiedzi nr 2
Dodam trochę dlaczego c
powinno być int
, nie char
. Załóżmy, że piszesz
#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;
}
I twój input.txt
jest
some text
Некоторый текст
Ъ - on this letter program will stop
w symbolu KOI8-R Ъ
mieć kod 255 == -1 (kiedy używasz char
). Dlatego w przypadku korzystania char
zamiast int
da ci output.txt
tylko z tym tekstem:
SOME TEXT
НЕКОТОРЫЙ ТЕКСТ
Jeśli chodzi o niedziałający kod z nawiasami: c=fgetc(f1)!=EOF
może być oznaczony przez kompilator jako c = (fgetc(f1)!=EOF)
, dlatego lepiej zawsze dodawać nawiasy.
Polecam używać flag -Wall -Werror
podczas kompilowania aplikacji. W takim przypadku „pominięcie” nawiasów spowoduje błąd:
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