2017-04-04 6 views
1

내가 여기서 무슨 일이 있었는지std :: fstream :: tellg()는 파일 커서 포인터를 잘못 출력합니까?

char c; 
cout << myFile.tellg() << endl; // Correctly outputs 0 (begining of file) 
myFile.read(&c, 1); 
cout << myFile.tellg() << endl; // Should output 1, but it outputs 
           // FFFFFFFFFFFFFFFA 
myFile.read(&c, 1); 
cout << myFile.tellg() << endl; // Should output 2, but it outputs 
           // FFFFFFFFFFFFFFFB 

를 사용, 내가 첫 번째 바이트를 읽고 싶어 할 때

std::fstream myFile { "C:/path/to/file.txt" }; 

를 사용하여 수입하는하는 std::fstream 있나요?

나는

midi_file.seekg(0, ios_base::beg); 

또는

midi_file.seekg(0, myFile.beg); 

을 퍼팅 시도하지만 바이트를 읽으려고 할 때마다 커서가 FFFFFFFFFFFFFFFA로 이동합니다.

편집 :

이 할 수있는 뭔가가 있는지 잘 모르겠지만, 내가 엔디안 테스트를했고, 이러한 결과입니다

bool endianness = *reinterpret_cast<short*>("10") & 1; // Outputs 1 

편집 2 :

다른 파일과 출력이 다르지만 그 이유는 무엇입니까?

4D 54 68 64 00 00 00 06 00 01 00 03 00 04 4D 54 
72 6B 00 00 00 A1 00 C0 69 00 90 3C 5A 01 41 5A 
01 45 5A 01 48 5A 01 49 5A 01 48 5A 01 45 5A 01 
41 5A 01 3C 5A 01 37 5A 01 33 5A 01 30 5A 01 30 
5A 01 30 5A 01 33 5A 01 37 5A 01 3C 5A 01 41 5A 
01 45 5A 01 48 5A 01 49 5A 01 48 5A 01 45 5A 01 
41 5A 01 3C 5A 01 37 5A 01 33 5A 01 30 5A 01 30 
5A 01 30 5A 01 33 5A 01 37 5A 01 3C 5A 01 41 5A 
01 45 5A 01 48 5A 01 49 5A 01 48 5A 01 45 5A 01 
41 5A 01 3C 5A 01 37 5A 01 33 5A 01 30 5A 01 30 
5A 01 30 5A 01 33 5A 01 37 5A 01 3C 5A 01 41 5A 
01 45 00 00 FF 2F 00 4D 54 72 6B 00 00 00 41 00 
C1 72 05 91 3C 5A 00 40 5A 00 43 5A 00 48 5A 0A 
35 5A 00 41 5A 00 44 5A 00 49 5A 0A 37 5A 00 40 
5A 00 43 5A 00 48 5A 0A 41 5A 00 47 5A 0A 30 5A 
00 40 5A 00 43 5A 00 48 5A 05 32 00 00 FF 2F 00 
4D 54 72 6B 00 00 00 26 00 C2 47 0A 92 50 64 01 
52 64 09 50 78 00 52 78 0A 50 00 01 52 00 09 50 
78 01 50 00 0A 52 00 00 50 00 00 FF 2F 00 

EDIT 3 : 여기

이 테스트의 전체 코드 :

여기

.midi 파일 HxD 찍은 파일의 바이트 데이터이다
#include <fstream> 
#include <iostream> 

int main() { 
    cout << std::hex << std::setfill('0') << std::uppercase; 

    fstream midi_file{ "D:/Descargas/OutFile.midi" }; 

    cout << midi_file.good() << endl; // Outputs 1 

    char c; 
    cout << midi_file.tellg() << endl; // Correctly outputs 0 (begining of file) 
    midi_file.read(&c, 1); 
    cout << midi_file.tellg() << endl; // Erroneously outputs FFFFFFFFFFFFFFFA 
    midi_file.read(&c, 1); 
    cout << midi_file.tellg() << endl; // Erroneously outputs FFFFFFFFFFFFFFFB 

    // Endianness test: 
    cout << (*reinterpret_cast<short*>("10") & 1) << endl; // Outputs 1 

    return 0; 
} 
+0

읽기 전과 후에 모두 'myFile' 상태가 양호합니까? – Angew

+0

@Angew 흠, myFile.badbit은 4를 반환하고 myFile.failbit은 2를 반환합니다. 그러나 myFile.bad()와 myFile.fail()은 모두'0'을 반환합니다. – Garmekain

+0

'std :: fstream'을 구성 할 때 중괄호'{}'가 오타라고 가정합니다. '()'이어야합니다. 그것도'{}'로 컴파일합니까? – freakish

답변

0

파일 열기 모드는 특수 문자를 잡으려고하지 ios::binary 모드에 있어야합니다.

1

tellg의 반환 값은 이 아니며입니다. 그것은 pos_type이며 따라야 할 규칙이 있지만 인쇄 할 때 이해할 수없는 규칙이 있습니다. http://en.cppreference.com/w/cpp/io/fpos

주된 목적은 탐색 작업이 저장된 위치로 돌아갈 수있게하는 것입니다.

또한 "endianness 테스트"는 매우 엉망입니다. 문자열을 짧은 것으로 재 해석합니까? C는 그런 식으로 작동하지 않습니다. 아마 당신이 사용했던 경우 "\x01\x00"

+0

문자열은 단지'const char *'이고, char 문자열은 2 바이트 길이이기 때문에 2 바이트 변수로 완벽하게 캐스팅 될 수 있습니다.이 예제에서는'short'입니다. 나는 '0'이 십진수로 '48'이므로 '& 1'부분은 그 문자의 숫자가 홀수인지 여부를 알려줍니다. ''0 ''이 아니고''1 ''인 경우''0 ''이 MSB이면 '(0x100 * 48 + 49) & 1'은 참을 반환하지만 '1' MSB 인 경우,'(0x100 * 49 + 48) & 1'는 false를 돌려줍니다. – Garmekain

+0

@Garmekain : 당신이 그렇게하는 것을 좋아한다면 나는 추측한다. 하지만 운이 좋았던 무식한 사람처럼 보입니다. –

+1

@Garmekain "완벽하게 캐스팅 될 수 있습니다."불가능합니다. 'reinterpret_cast'로'const'를 캐스팅 할 수 없기 때문에 컴파일하지 않아야합니다. 컴파일러가 여러분에게 약간의 여유를 주며 컴파일을 허용 할 때, 잘못된 정렬 때문에 런타임에 크래시 될 수 있습니다. UB를 전시하고 NOP로 바꾸기 때문에 전체 프로그램을 폐기하십시오. –