본문 바로가기
프로그래밍/C·C++

char ch = getchar();의 문제의 원인

by ITPro 2010. 8. 11.

많은 분이 잘못 생각하시고 있는 부분이 있는데, char ch = getchar();의 문제의 원인은 char가 signed인지 unsigned인지와 전혀 관련이 없습니다. 단지 문제의 결과 발생하는 현상이 char가 signed일 때와 unsigned일 때가 다를 뿐입니다.

자세히 설명하자면,

정상적인 경우:
맨페이지를 보면 getchar() 함수는 결과값을 unsigned char로 읽어서 int형으로 캐스팅한 결과를 리턴한다고 하고 있습니다. 결과를 제대로 int형으로 받으면 0 ~ 255의 정상적인 결과와 EOF라는 에러를 저장할 수 있습니다.

문제의 원인:
getchar() 함수는 257가지의 결과가 존재합니다. (256가지 정상적 결과 + EOF) 이 범위는 (signed이든 unsigned이든) char 형이 저장할 수 있는 256가지보다 크기 때문에 모든 결과를 받을 수가 없습니다. 즉, 어느 두 결과값은 겹칠 수 밖에 없습니다.

문제의 결과:
(EOF가 int형 -1이라 가정합시다)
char이 signed일 때와 unsigned일 때

공통점: 정상적인 결과값 255와 EOF를 구분할 수 없습니다.

차이점:

while ((ch = getchar()) != EOF)
    putchar(ch);
에서
ch가 signed일 때 - 정상적인 결과값인 255를 받았을 때 EOF를 받은 것과 같이 동작하는 문제가 있습니다.
-> signed char값에 255를 넣으면 -1이 되므로 식이 거짓이 됨
ch가 unsigned일 때 - EOF를 받았을 때 정상적인 결과값인 255를 받은 것과 갈이 동작하는 문제가 있습니다.
-> unsigned char값에 EOF를 넣으면 255가 되므로 식이 참이 됨

결론:
getchar()의 결과는 항상 int형으로 받아야 합니다. char형으로 받는건 언제나 잘못된 코드입이다. char로 받았는데도 잘 돌아갔다면, 다루는 파일에 우연하게도 255에 해당하는 값이 없었을 뿐이죠. 이식성 없는 형변환, char이 내부적으로 signed인지 unsigned인지는 관계가 없습니다.

정리가 되셨기 바랍니다

반응형

'프로그래밍 > C·C++' 카테고리의 다른 글

리눅스 로케일 세팅  (0) 2010.08.11
리눅스 curses.h 설명  (0) 2010.08.11
리눅스 curses.h 사용 예  (0) 2010.08.11
전역변수&extern  (0) 2010.08.11
getc(), getch(), getchar()  (1) 2010.08.11

바로가기