씨
파일에서 문자 "x"가 유실되었습니다. 그것을 찾기 위해 프로그램이 작성되었습니다.
#include <stdio.h>
#include <stdlib.h>
int main(int argc, char *argv[]) {
FILE* fp = fopen("desert_file", "r");
char letter;
char missing_letter = argv[1][0];
int found = 0;
printf("Searching file for missing letter %c...\n", missing_letter);
while( (letter = fgetc(fp)) != EOF ) {
if (letter == missing_letter) found = 1;
}
printf("Whole file searched.\n");
fclose(fp);
if (found) {
printf("Hurray, letter lost in the file is finally found!\n");
} else {
printf("Haven't found missing letter...\n");
}
}
컴파일되어 실행되었고 마침내 소리 쳤다.
Hurray, letter lost in the file is finally found!
몇 년 동안 새로운 사람이 와서 코드를 최적화 할 때까지 편지는 이런 식으로 구해졌습니다. 그는 데이터 유형에 익숙했으며 범위가 더 넓고 오버플로에 대해 약간의 보호를 제공하므로 음수가 아닌 값에 대해 부호있는 것보다 부호없는 것을 사용하는 것이 좋습니다. 그래서 그는 int를 unsigned int로 변경했습니다 . 그는 또한 그들이 음이 아닌 가치를 가지고 있음을 알기에 충분히 아스키를 알고있었습니다. 그래서 그는 또한 char를 unsigned char로 변경했습니다 . 그는 코드를 작성하고 그가 한 좋은 일을 자랑스럽게 집으로 돌아갔다. 프로그램은 다음과 같습니다 :
#include <stdio.h>
#include <stdlib.h>
int main(int argc, char *argv[]) {
FILE* fp = fopen("desert_file", "r");
unsigned char letter;
unsigned char missing_letter = argv[1][0];
unsigned int found = 0;
printf("Searching file for missing letter %c...\n", missing_letter);
while( (letter = fgetc(fp)) != EOF ) {
if (letter == missing_letter) found = 1;
}
printf("Whole file searched.\n");
fclose(fp);
if (found) {
printf("Hurray, letter lost in the file is finally found!\n");
} else {
printf("Haven't found missing letter...\n");
}
}
그는 다음날 혼란에 돌아 왔습니다. 문자 "a"가 누락되었고 "abc"를 포함하는 "desert_file"에 있어야했지만 프로그램이 영원히 인쇄 만 검색했습니다.
Searching file for missing letter a...
그들은 직원을 해고하고 이전 버전으로 롤백하여 작업 코드에서 데이터 유형을 최적화해서는 안된다는 것을 기억했습니다.
그러나 그들이 여기서 배워야 할 교훈은 무엇입니까?
우선, ascii 테이블을 보면 EOF가 없다는 것을 알 수 있습니다. EOF는 문자가 아니라 fgetc ()에서 반환 된 특수 값이기 때문에 int로 확장 된 문자를 반환하거나 파일의 끝을 나타내는 -1을 반환 할 수 있기 때문입니다.
우리가 signed char을 사용하는 한 모든 것이 잘 작동합니다-50과 같은 char은 fgetc ()에 의해 int와 50으로 확장됩니다. 그런 다음 다시 char로 변환하고 여전히 50을 갖습니다. -1 또는 fgetc ()에서 나오는 다른 출력에서도 마찬가지입니다.
그러나 서명되지 않은 문자를 사용하면 어떻게되는지보십시오. fgetc ()에서 char로 시작하여 int로 확장 한 다음 서명되지 않은 char을 원합니다. 유일한 문제는 부호없는 char에서 -1을 유지할 수 없다는 것입니다. 프로그램이 더 이상 EOF와 같지 않은 255로 저장합니다.
경고
ANSI C 문서의 사본
에서 3.1.2.5 유형을 살펴보면 char이 서명되었는지 여부는 전적으로 구현에 달려 있다는 것을 알 수 있습니다. 따라서 코드에 숨어있는 매우 까다로운 버그를 발견했을 때 아마도 그 사람은 약탈해서는 안됩니다. 컴파일러를 변경하거나 다른 아키텍처로 이동할 때 나올 수 있습니다. 그런 경우에 버그가 나면 누가 해고 될지 궁금합니다.)
추신. 프로그램은 Paul A. Carter가 PC Assembly Language에서 언급 한 버그를 중심으로 구축되었습니다.