std::fstream::tellg() 输出文件光标指针不正确?
std::fstream::tellg() outputs file cursor pointer incorrectly?
我有一个 std::fstream
,我使用
导入的
std::fstream myFile { "C:/path/to/file.txt" };
当我要读取第一个字节时,我使用
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
这里发生了什么?
我试过
midi_file.seekg(0, ios_base::beg);
或
midi_file.seekg(0, myFile.beg);
但每当我尝试读取一个字节时,光标都会移动到 FFFFFFFFFFFFFFFA
。
编辑:
我不知道这是否有关系,但我做了字节顺序测试,结果如下:
bool endianness = *reinterpret_cast<short*>("10") & 1; // Outputs 1
编辑 2:
文件已损坏,因为输出与另一个文件不一样,但这是为什么?
这是文件中的字节数据,取自 HxD,它是一个 .midi
文件:
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
编辑 3:
这里是这个测试的完整代码:
#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;
}
tellg
的 return 值 不是 一个数字。它是一个 pos_type
,它有一些需要遵循的规则,但在打印时易于理解不是其中之一。参见 http://en.cppreference.com/w/cpp/io/fpos
它的主要目的是允许搜索操作 return 到保存的位置。
另外,你的 "endianness test" 非常非常混乱。将字符串重新解释为短字符串? C 不是那样工作的。 可能 如果你用过 "\x01\x00"
文件打开模式必须是 ios::binary
模式才能不捕获特殊字符。
我有一个 std::fstream
,我使用
std::fstream myFile { "C:/path/to/file.txt" };
当我要读取第一个字节时,我使用
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
这里发生了什么?
我试过
midi_file.seekg(0, ios_base::beg);
或
midi_file.seekg(0, myFile.beg);
但每当我尝试读取一个字节时,光标都会移动到 FFFFFFFFFFFFFFFA
。
编辑:
我不知道这是否有关系,但我做了字节顺序测试,结果如下:
bool endianness = *reinterpret_cast<short*>("10") & 1; // Outputs 1
编辑 2:
文件已损坏,因为输出与另一个文件不一样,但这是为什么?
这是文件中的字节数据,取自 HxD,它是一个 .midi
文件:
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
编辑 3:
这里是这个测试的完整代码:
#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;
}
tellg
的 return 值 不是 一个数字。它是一个 pos_type
,它有一些需要遵循的规则,但在打印时易于理解不是其中之一。参见 http://en.cppreference.com/w/cpp/io/fpos
它的主要目的是允许搜索操作 return 到保存的位置。
另外,你的 "endianness test" 非常非常混乱。将字符串重新解释为短字符串? C 不是那样工作的。 可能 如果你用过 "\x01\x00"
文件打开模式必须是 ios::binary
模式才能不捕获特殊字符。