#c #io
#c #io
Вопрос:
У меня есть следующая программа на C , и я запустил ее с помощью Visual Studio 2008 в Windows 7. Я получаю, а затем удаляю символ. После этого позиция файла изменится. Почему? Как мне обойти эту проблему?
test.txt (ссылка для скачивания ниже, если вы хотите)
/* Comment 1 */
/* Comment 2 */
#include <fstream>
int main (int argc, char ** argv) {
char const * file = "test.txt";
std::fstream fs(file, std::ios::in);
std::streampos const before = fs.tellg();
// replacing the following two lines with
// char c = fs.peek(); results in the same problem
char const c = fs.get();
fs.unget();
std::streampos const after = fs.tellg();
fs.seekg(after);
char const c2 = fs.get();
fs.close();
return 0;
}
c: 47 '/' char
c2: -1 'ÿ' char
before: {_Myoff=0 _Fpos=0 _Mystate=0 } std::fpos<int>
after: {_Myoff=0 _Fpos=-3 _Mystate=0 } std::fpos<int>
Добавление | std::fstream::binary
в конструктор, похоже, решает проблему. Возможно, это связано с новыми строками в файле? Если да, то почему это влияет на код, который даже не приближается к чтению новой строки?
Обновлено с поиском в позиции after и получением другого символа.
Кажется, что сохранение через блокнот против Vim имеет значение. Сохранение через блокнот позволяет потоку работать нормально.
Я загрузил файл в Google docs, если вы хотите его удалить:
Комментарии:
1. Кстати, вы можете использовать
std::ios::in
,fstream
наследует отios
.2. Обновил мой ответ ниже.
Ответ №1:
Хорошо, используя ваш входной файл, я вижу то же поведение, что и вы. После некоторых экспериментов, похоже, что файл был в формате Unix, затем были отредактированы символы ^M (по крайней мере, так я смог его воспроизвести).
Чтобы исправить это, я отредактировал файл в Vim, выполнил «:set ff = dos», затем добавил и удалил символ, чтобы испортить файл, а затем сохранил его.
Комментарии:
1. Что касается почему, я могу только предположить, что это связано с тем, как std::streams обрабатывает символы EOL. Я просмотрел двоичные представления обоих файлов, и символы EOL и EOF — единственные различия, которые я заметил.
2. Ха-ха, теперь у вас неприятный компьютерный вирус!
Ответ №2:
Позиция файла ведет себя так, как ожидалось:
// unget.cpp
#include <fstream>
#include <iostream>
int main ()
{
char const * file = "test.txt";
std::fstream fs(file, std::fstream::in);
std::cout << fs.tellg() << std::endl; // 0
char c = fs.get();
std::cout << fs.tellg() << std::endl; // 1
fs.unget();
std::cout << fs.tellg() << std::endl; // 0
fs.close();
return 0;
}
Сборка и запуск:
$ clang unget.cpp
$ ./a.out
0
1
0
Или я не понимаю, в чем проблема.