Почему я не могу читать и добавлять с помощью std::fstream в Mac OS X?
Рассмотрим следующую программу на C++, которая берет файл и печатает каждую строку. Это фрагмент более крупной программы, куда я позже добавляю файл, основываясь на том, что вижу.
#include <fstream>
using std::fstream;
#include <iostream>
#include <string>
using std::string;
int main()
{
fstream file("file.txt", fstream::in | fstream::out | fstream::app);
string line;
while (std::getline(file, line))
std::cerr << line << std::endl;
return 0;
}
Теперь примените эту версию file.txt
(Одно слово в первой строке, за которым следует новая строка):
Rain
На моей машине (Snow Leopard) эта ничего не распечатывает. При ближайшем рассмотрении первый вызов getline завершается неудачно. Странно, но и если я добавлю вторую строку, ничего не получится!
Кто-нибудь может разгадать эту тайну?
2 ответа
Когда ты сказал:
fstream file("file.txt", fstream::in | fstream::out | fstream::app);
Вы открываете файл в режиме добавления - т.е. в конце. Просто откройте его в режиме чтения:
fstream file("file.txt", fstream::in );
или используйте ifstream:
ifstream file("file.txt" );
И, конечно, как предлагает Уорвикер, вы всегда должны проверять, что открытие прошло успешно.
Если вы решили открыть в режиме добавления, вы можете явно переместить указатель чтения:
#include <fstream>
#include <iostream>
#include <string>
using namespace std;
int main() {
fstream file( "afile.txt", ios::in | ios::out | ios::app );
if ( ! file.is_open() ) {
cerr << "open failed" << endl;
return 1;
}
else {
file.seekg( 0, ios::beg ); // move read pointer
string line;
while( getline( file, line ) ) {
cout << line << endl;
}
}
}
Редактировать: Кажется, что комбинация флагов, используемых при открытии файла, приводит к специфическому поведению реализации. Приведенный выше код работает с g++ в Windows, но не с g++ в Linux.
Вы должны проверить, был ли файл действительно открыт:
if (!file)
std::cerr << "Oh dear" << std::endl;
Обновление: фактически файл, вероятно, был открыт, но находится в режиме добавления - см. Ответ Нейи.
Обновление 2: хорошо, снова не так. В Leopard G ++, по крайней мере, файл не будет открыт, потому что app
флаг несовместим с in
флаг. Таким образом, вышеупомянутая проверка напечатает Oh dear
,
В MSVC++ он идет вперед и открывает файл, очевидно, с позиции чтения в начале, что объясняет, почему другие люди видели, как это работает, и я прошу прощения за сомнение в их правдивости!