2017-11-13 26 views
1

나는 (라인 유닉스 스타일로 끝나는) 다음과 같은 C 코드윈도우에서`fseek (..., 0, SEEK_CUR)`이 실패하는 이유는 무엇입니까?

는 MinGW-W64와 win10 ( gcc version 7.1.0 (x86_64-posix-seh-rev0, Built by MinGW-W64 project))에
#include <stdio.h> 

int main() 
{ 
    FILE * file = fopen("ans.txt", "r+"); 
    printf("%ld", ftell(file)); // prints 0 
    fgetc(file); 
    printf("%ld", ftell(file)); // prints -18 
    printf("%d", fseek(file, 0, SEEK_CUR)); // -1 
    printf("%ld", ftell(file)); // prints 150 
    fclose(file); 
    return 0; 
} 

및 Visual Studio 2017 (CL.EXE 버전 Microsoft (R) C/C++ Optimizing Compiler Version 19.11.25547)
ans.txt 파일이 테스트를했습니다

line 1 
line 2 
line 3 
line 4 
line 5 
line 6 
line 7 
line 8 
line 9 
line 10 
line 11 
line 12 
line 13 
line 14 
line 15 
line 16 
line 17 
line 18 
line 19 
line 20 

하지만 이진 모드에서 파일을 열거 나 줄 끝 스타일을 'Windows/Mac OS 9'로 변경하면 모든 것이 올바르게됩니다.
Windows crt와 관련이 있습니까?

+3

을 라인 엔딩. –

+1

파일을 성공적으로 열 었는지 확인 했습니까? 코드가 실패한 경우 크래시가 발생하지 않아야합니다. 숫자 뒤에 줄 바꿈 (또는 공백)을 인쇄하는 것이 현명합니다. –

+0

'fgets()'의 의미는 무엇입니까? 귀하의 코드는 그것을 호출하지 않습니다? 더 정확히 말하자면, 우리가 현재 검토 할 것을 요구하는 코드는'fgets()'를 호출하지 않습니다. 아마도 이것은 우리에게 보여주고있는 것이 테스트중인 코드와 같지 않다는 것을 의미하며 그 차이는 문제의 일부를 포함합니다. 우리가 볼 수없는 코드의 문제점을 추론 할 수는 없습니다. –

답변

3

이는 MSDN here에 설명되어 있습니다 : 텍스트 모드, fseek과 및 _fseeki64에서 열린 스트림

는 캐리지 리턴 - 라인 피드 번역 fseek과 발생할 수 있기 때문에 _fseeki64 예기치 않은 결과를 생산, 사용을 제한했다. 유일한 fseek는 텍스트 모드에서 연 스트림에서 작동하도록 보장 _fseeki64 작업은 다음과 같습니다

  • 는 원래 값의 0 상대의 오프셋으로 추구.

  • _fseeki64를 사용하는 일 때 fseekor _ftelli64를 사용할 때 ftell 호출에서 반환 된 오프셋 값이있는 파일의 시작 부분부터 검색합니다.

열기 바이너리 모드로 파일 ... 그리고 좀 더 예측 가능한 결과를 얻을 : 당신이 윈도우 스타일을 가지고하도록되어 Windows에서 비 바이너리 모드로 파일을 열 경우

FILE * file = fopen("ans.txt", "rb+"); 
+1

오프셋 0을 사용하여 코드가 검색됩니다 –

+0

예. 'fseek' 이전의'fgetc' 호출은 스트림을 우습게 만듭니다. CRT 소스를 통해 디버깅 할 시간이 없으므로 잘못된 것을 확인해야합니다. 원본 소스 파일이 유닉스 스타일의 라인 엔딩이라는 점을 감안할 때, OP는 텍스트 대신 바이너리로 여는 것으로 모든 번역 작업과 관련 부작용을 피할 수 있습니다. – selbie

+0

이것은 Windows의 이상한 특질이 아닙니다. C 표준은 텍스트 모드에서 열린 파일에 대한 fseek 및 ftell의 동일한 제한 사항을 설명합니다. ftell의 리턴 값은 본질적으로 fseek에 대한 입력으로 만 유용한 불투명 한 마법 값입니다. –