먼저 fseek
또는 ftell
과 같이 실패시 설정되는 errno
을 확인하여 프로그램에 잘못된 내용을 알려달라고 요청하십시오.
기타 (tonio & LatinSuD)는 stdin을 처리하는 것과 파일 이름을 확인하는 실수를 설명했습니다. 즉, 먼저 argc
(인수 개수)을 확인하여 if (argc > 1)
으로 지정된 명령 줄 매개 변수가 있는지 확인하고 -
을 특별한 경우로 stdin
으로 처리하십시오.
매개 변수를 지정하지 않으면, 입력 파일이 아닌 스트림 인 stdin
에서 온 (예정)하고, fseek
함수가 실패 가정합니다. 당신이 (줄 바꿈 문자 후행 포함) 읽기 바이트 수를 계산하는 파일에 디스크 중심의 라이브러리 함수 (즉, fseek
및 ftell
)를, 당신은 단순히 한 사용할 수 없습니다 스트림의 경우
EOF
를 수신 할 때까지 (파일 끝).
대용량 파일을 사용하는 경우 (텍스트) 파일의 바이트를보다 효율적으로 읽으려면 문자 배열에 fgets
을 사용하여 속도를 높일 수 있습니다. 이진 파일의 경우 fopen(const char* filename, "rb")
을 사용해야하고 fgetc/fgets
대신 fread
을 사용해야합니다.
스트림에서 읽을 때 오류를 감지하기 위해 바이트 계산 방법을 사용하는 경우 feof(stdin)
/ferror(stdin)
을 확인할 수도 있습니다.
아래 샘플은 C99 규격 및 휴대용이어야합니다.
#include <stdio.h>
#include <stdlib.h>
#include <errno.h>
#include <string.h>
long getSizeOfInput(FILE *input){
long retvalue = 0;
int c;
if (input != stdin) {
if (-1 == fseek(input, 0L, SEEK_END)) {
fprintf(stderr, "Error seek end: %s\n", strerror(errno));
exit(EXIT_FAILURE);
}
if (-1 == (retvalue = ftell(input))) {
fprintf(stderr, "ftell failed: %s\n", strerror(errno));
exit(EXIT_FAILURE);
}
if (-1 == fseek(input, 0L, SEEK_SET)) {
fprintf(stderr, "Error seek start: %s\n", strerror(errno));
exit(EXIT_FAILURE);
}
} else {
/* for stdin, we need to read in the entire stream until EOF */
while (EOF != (c = fgetc(input))) {
retvalue++;
}
}
return retvalue;
}
int main(int argc, char **argv) {
FILE *input;
if (argc > 1) {
if(!strcmp(argv[1],"-")) {
input = stdin;
} else {
input = fopen(argv[1],"r");
if (NULL == input) {
fprintf(stderr, "Unable to open '%s': %s\n",
argv[1], strerror(errno));
exit(EXIT_FAILURE);
}
}
} else {
input = stdin;
}
printf("Size of file: %ld\n", getSizeOfInput(input));
return EXIT_SUCCESS;
}
'feof'는 이전에 스트림에서 읽으려고 시도 했으므로 까다로운 작업입니다. (그리고 그렇게하면 실패 이유를 확인할 수도 있습니다.)이 상황에서 어떻게 사용하는지 제안하는 방법은 분명하지 않습니다. – jamesdlin