Эта проблема вызвана libstdC++, используя разницу между текущим оставшимся буфером с lseek64
, чтобы определить текущее смещение.
Буфера устанавливаются с помощью возвращаемого значения read
, что для режима текстового файла на окнах возвращает количество байт, которые были введены в буфер после преобразования лицевой линии (т.е. 2 байта \r\n
лицевой линии преобразуются в \n
, окна также, кажется, добавляют ложную новую строку в конец файла).
lseek64
однако (что с результатами MinGW в вызове _lseeki64
) возвращает текущее абсолютное положение файла и как только два значения вычитаются вы в конечном итоге со смещением, который отстоит от 1 для каждого оставшегося символа новой строки в текстовом файле (+1 для дополнительной строки перевода строки).
В следующем коде должна отображаться проблема, вы даже можете использовать файл с одним символом и без новой строки из-за дополнительной строки, вставленной окнами.
#include <iostream>
#include <fstream>
int main()
{
std::ifstream f("myfile.txt");
for (char c; f.get(c);)
std::cout << f.tellg() << ' ';
}
Для файла с одним a
характером я получаю следующие выходные данные
2 3
Ясно охлаждает 1 для первого вызова tellg
. После второго вызова позиция файла верна, поскольку конец был достигнут после учета дополнительной строки.
Помимо открытия файла в двоичном режиме, вы можете обойти проблему путем отключения буферизации
#include <iostream>
#include <fstream>
int main()
{
std::ifstream f;
f.rdbuf()->pubsetbuf(nullptr, 0);
f.open("myfile.txt");
for (char c; f.get(c);)
std::cout << f.tellg() << ' ';
}
, но это далеко от идеала.
Надеюсь, что mingw/mingw-w64 или gcc могут это исправить, но сначала нам нужно будет определить, кто будет ответственен за его исправление. Я полагаю, что основная проблема связана с реализацией MS lysek, которая должна возвращать соответствующие значения в соответствии с тем, как файл был открыт.
что ком пиллер вы используете? – user657267
Я использую компилятор MinGW C++. – Michael
Что происходит, если вы не используете 'binary'? – 0x499602D2