2012-09-13 7 views
0

가능한 중복 누락 :
fgetc does not identify EOF
fgetc, checking EOF는 EOF 유닉스 파일

내가 유닉스에서 파일을 생성하고 "file.txt를"로 이름을했다. C 프로그램에서 파일 내용을 읽으려고했습니다. EOF 문자를받을 수 없습니다. 유닉스는 파일 생성시 EOF 문자를 저장하지 않습니까? 그래서 여기

C.

를 사용하여 유닉스 생성 된 파일에서 EOF을 읽을 수있는 다른 방법은 무엇인가하면 내가 명시 적으로 EOF도 감지 CTRL + D을주는 경우에 코드 샘플을

int main(){ 
File *fp; 
int nl,c; 
nl =0; 
fp = fopen("file.txt", "r"); 
while((c = fgetc(fp)) != EOF){ 
    if (c=='\n') 
    nl++; 
} 
return 0; 
} 

있어 내가 char c을 사용할 때.

+2

가능한 [fgetc은 EOF를 식별하지 못합니다] (http://stackoverflow.com/questions/3977223/fgetc-does-not-identify-eof), http://stackoverflow.com/questions/11057259도 참조하십시오./fgetc-checking-eof 및 많은 다른 많은 파일들 – Mat

+1

참고 : EOF는 "파일에 저장"되어 있지 않으며 입출력 기능이 파일 끝에 도달했음을 알려주는 유일한 방법입니다. 끝에는 매직 바이트가 저장되지 않습니다. – Mat

+2

'File * fp;가 아닌'FILE * fp;가되어야하며, 변수'fp'를 통해 무엇인가를 읽기 전에 파일이 성공적으로 열렸는 지 확인해야합니다. –

답변

4

c의 유형 char 경우이 일어날 수 없습니다 int (그리고 char는 컴파일러에 서명, 당신은 CHAR_MIN에서의 값을 검사하여이를 확인할 수 있습니다.)

EOF의 값은 C 표준에 따라 음수입니다.

따라서 EOF에서 unsigned char으로 암시 적으로 캐스팅하면 EOF의 실제 값이 손실되고 비교는 항상 실패합니다.

업데이트 : 먼저 해결해야 할 더 큰 문제가 있습니다. c = fgetc(fp) != EOF이라는 표현식에서는 fgetc(fp) != EOF이 먼저 평가되고 (0 또는 1로) 값이 c에 할당됩니다. 파일에 문자가 하나 이상있는 경우 fgetc(fp) != EOF은 0으로 평가되고 while 루프 본문은 실행되지 않습니다. 다음과 같이 괄호를 추가해야합니다 : (c = fgetc(fp)) != EOF.

0

변수를 선언하는 방법을 나타내지 않으므로 cint이 아니라 char이 아니어야합니다.

3

괄호가 누락되었습니다. 해야합니다

while((c = fgetc(fp)) != EOF) 
+0

:) 불행히도이 .. –

+0

이것은 코드 컴파일을 방지하지만 런타임 오류를 설명하지는 않습니다. 또한 질문의 코드는 컴파일 된 코드가 아니므로 항상 디버깅을 어렵게 만듭니다. –

+0

어떻게 코드가 컴파일되지 않습니까? 부등호 연산자의 결과 값을 스칼라 변수에 대입하는 것은 완벽하게 유효합니다. –

1

기억하십시오 : fgetc()char이 아니라 int을 반송합니다. int을 반환해야합니다. 반환 값 집합에는 가능한 모든 유효한 문자와 별도의 (음수) EOF 표시기가 포함되어 있기 때문입니다. 유형 char이 컴파일러로 서명

  1. 경우, EOF로 유효한 문자를 감지 : 당신이 c 대신 int의 대한 유형 char를 사용하는 경우

    는 두 가지 함정이있다. 종종, 문자 ÿ (y- 움라우트, 공식적으로는 라틴어로 LASE CASE Y WITH DIAERESIS, U + 00FF, ISO 8859-1 라틴어 1 코드 집합의 16 진수 코드 0xFF)는 EOF와 동등한 것으로 탐지됩니다. 그것은 유효한 문자입니다.

  2. 유형 char이 서명되지 않은 경우 비교는 사실이 아닙니다.

모두 문제가 심각하고, 모두가 올바른 형식을 사용하여 피할 수있다 : 유형이 FILE하지 File입니다

FILE *fp = fopen("file.txt", "r"); 
if (fp != 0) 
{ 
    int c; 
    int nl = 0; 
    while ((c = fgetc(fp)) != EOF) 
     if (c == '\n') 
      nl++; 
    printf("Number of lines: %d\n", nl); 
} 

하는 것으로. fp을 통해 읽기 전에 파일이 열려 있는지 확인해야합니다. 내가 char c를 사용할 때


내가 명시 적으로 CTRL + D를주는 경우에

는 EOF도 감지된다.

이것은 컴파일러가 char을 서명 된 유형으로 제공함을 의미합니다. 또한 ÿ가 포함 된 파일에서 라인 수를 정확하게 계산할 수 없다는 것을 의미합니다.


CP/M 및 DOS와 달리 Unix는 EOF를 나타내는 문자를 사용하지 않습니다. 읽을 문자가 더 이상 없을 때 EOF에 도달합니다. 많은 사람들을 혼란스럽게하는 이유는 단말기에 특정 키 조합을 입력하면 프로그램이 EOF를 감지한다는 것입니다. 실제로 일어나는 일은 터미널 드라이버가 문자를 인식하고 읽지 않은 문자를 프로그램에 보냅니다. 읽지 않은 문자가 없으면 프로그램은 0 바이트를 반환하며 이는 파일 끝에 도달했을 때와 동일한 결과입니다. 따라서 문자 조합 (종종은 아니지만 항상 Ctrl-D)이 프로그램에 'EOF 보내기'를 표시합니다. 그러나 문자가 cat >file을 사용하는 경우 파일에 저장되지 않습니다. 또한 control-D가 들어있는 파일을 읽으면 바이트 값이 0x04 인 완벽한 문자입니다. 프로그램이 control-D를 생성하여 프로그램에 보내는 경우 프로그램에 EOF가 표시되지 않습니다. 이것은 유닉스 터미널 (tty 및 pty-teletype 및 pseudo-teletype - 장치)의 속성입니다.