2016-09-05 6 views
1

저는 C의 초보자입니다. 내 자신의 버전을 base64으로 만들려고합니다. 프로그램은 stdin에서 입력을 받아서 stdout에 해당하는 base64를 출력합니다. 내 프로그램을 바이너리 파일에 대해 테스트하는 동안 stdin에서 fread -ing이 실제로 EOF에 도달하기 전에 잠깐 숏 카운트를 반환하는 것으로 보였다. 여기 fread가 이진 파일로 EOF를 조기에 알려주고 있습니다.

내 주요 방법의 중요한 부분이다

int main(void) 
{ 
    unsigned char buffer[BUFFER_SIZE]; 
    unsigned char base64_buffer[BASE64_BUFFER]; 

    while (1) 
    { 
     TRACE_PUTS("Reading in data from stdin..."); 
     size_t read = fread(buffer, 1, sizeof(buffer), stdin); /* Read the data in using fread(3) */ 

     /* Process the buffer */ 

     TRACE_PRINTF("Amount read: %zu\n", read); 
     TRACE_PUTS("Beginning base64 encode of buffer"); 
     size_t encoded = base64_encode(buffer, read, base64_buffer, sizeof(base64_buffer)); 

     /* Write the data to stdout */ 
     TRACE_PUTS("Writing data to standard output"); 
     ... 

     if (read < sizeof(buffer)) 
     { 
      break; /* We reached EOF or had an error during the read */ 
     } 
    } 

    if (ferror(stdin)) 
    { 
     /* Handle errors */ 
     fprintf(stderr, "%s\n", "There was a problem reading from the file."); 
     exit(1); 
    } 

    puts(""); /* Output a newline before finishing */ 

    return 0; 
} 

시피 메인 루프 fread가 버퍼에 표준 입력의 모든 반복 호출 후 최종 검사에서 판독 량이 작 으면 버퍼의 크기보다 그렇다면 오류 (0이 반환 된 경우) 또는 EOF에 도달 한 것으로 가정하고 루프를 종료합니다. 수를 반환) 성공

, FREAD()와에 fwrite (:

가 나는 FREAD의 맨 페이지에서이 인용을 기반으로, 오히려 단지 != 0보다 < sizeof(buffer)read을 확인 OK라고 가정하고 읽거나 쓰여진 물건들. 이 숫자는 크기가 1 일 때만 전송 된 바이트 수입니다. 오류가 발생하거나 파일의 끝에 도달하면 반환 값은 짧은 항목 수 (또는 0)입니다.

이는 전체 버퍼가 읽히지 않으면 EOF에 도달 함을 의미합니다. 그 설립과 함께

이 내가 cat /bin/echo에 내 응용 프로그램을 실행했을 때 얻을 추적입니다 :

$ cat /bin/echo | bin/base64 >/dev/null # only view the trace output 
TRACE: C:/Users/James/Code/c/base64/main.c:23: Reading in data from stdin... 
TRACE: C:/Users/James/Code/c/base64/main.c:28: Amount read: 600 
TRACE: C:/Users/James/Code/c/base64/main.c:29: Beginning base64 encode of buffer 
TRACE: C:/Users/James/Code/c/base64/main.c:43: Writing data to standard output 
TRACE: C:/Users/James/Code/c/base64/main.c:23: Reading in data from stdin... 
TRACE: C:/Users/James/Code/c/base64/main.c:28: Amount read: 600 
TRACE: C:/Users/James/Code/c/base64/main.c:29: Beginning base64 encode of buffer 
TRACE: C:/Users/James/Code/c/base64/main.c:43: Writing data to standard output 
TRACE: C:/Users/James/Code/c/base64/main.c:23: Reading in data from stdin... 
TRACE: C:/Users/James/Code/c/base64/main.c:28: Amount read: 600 
TRACE: C:/Users/James/Code/c/base64/main.c:29: Beginning base64 encode of buffer 
TRACE: C:/Users/James/Code/c/base64/main.c:43: Writing data to standard output 
TRACE: C:/Users/James/Code/c/base64/main.c:23: Reading in data from stdin... 
TRACE: C:/Users/James/Code/c/base64/main.c:28: Amount read: 569 
TRACE: C:/Users/James/Code/c/base64/main.c:29: Beginning base64 encode of buffer 
TRACE: C:/Users/James/Code/c/base64/main.c:43: Writing data to standard output 

$ 

을 그리고 여기에 실제로 얼마나 /bin/echo 큰 : 당신이 볼 수 그래서

$ cat /bin/echo | wc -c 
28352 

, 전체 파일은 28352 바이트이지만 내 앱은 멈추기 전에 약 2400 개 정도만 읽습니다. 왜 그런가? fread은 널 터미네이터를 특별히 처리합니까?

GCC와 함께 MinGW-w64를 사용하고 있습니다. 감사.

답변

3

Windows 사용자입니까? 예, 경로 이름은 C:이므로 시작하십시오. 파일에 Control-Z ('\x1A' 또는 '\32') 문자가있을 것입니다. 어떤 식 으로든 조정할 수 없다면 표준 입력을 이진 파일로 처리하지 않으므로 Control-Z는 입력의 끝을 표시합니다.

'어떻게 든'모드를 조정할 수있는 방법은 _set_fmode()입니다. 그러나, 당신이 _setmode() 필요 가능성이 높습니다 :

_setmode(fileno(stdin), O_BINARY); 

내가 그 그렇게위한 최상의 또는 유일한 방법인지에 대한 판단을 보유하고 있습니다. 가능한 한 매뉴얼을 연구 할 수 있습니다. Microsoft 세계에서 fileno() 또는 아마도 _fileno()을 테스트 할 방법이 없습니다.