Открытие потока для чтения / записи (бинарный)

В этой программе пользователю доступно несколько опций: Опция 1: запись записи (завершается клавишей EOF). Вариант 2: отображает записи. Вариант 3: выход из программы.

Пользователь может затем повторить этот процесс. Я хочу избежать перезаписи записей путем поиска в конце файла и обеспечения правильности вызовов close() и open().

После объявления:

fstream fs("file", ios_base::in | ios_base::out | ios_base::binary);

нужно ли явно вызывать open;

fs.open("file", ios_base::in | ios_base::binary);

если это необходимо: должен ли быть указан двоичный режим? и нужно ли очищать поток перед последовательной записью?

struct record
{
    char firstname[MAX], lastname[MAX];
    int score;
};

int main(){

  record r;
  // must the modes be listed in a particular order?
  fstream fs("file", ios_base::in |ios_base::out | ios_base::binary);

  if(choice == 1) // option 1 for writing 
  {
    fs.clear(); // is it necessary to clear?
    // is it necessary to explicitly call open [and close] within 'if'
    fs.open("file", ios_base::in | ios_base::binary); 
    fs.seekp(0, ios_base::end); //attempt to avoid overwriting previous records 

    fs.write( (char *)&r, sizeof(r) );
    fs.close(); // is it best to close the file here...
  } 
  else if(choice == 2){ /*Display records*/ }
  else if(choice == 3){ exit(1); }

  /* would it be incorrect to fs.close() here and not call fs.open() */

  return 0;
}

1 ответ

После объявления:

fstream fs("file", ios_base::in | ios_base::out | ios_base::binary);

нужно ли явно вызывать open;

fs.open("file", ios_base::in | ios_base::binary);

Файловые потоки могут быть открыты в их конструкторах или путем вызова функции-члена open(), Если файл уже был открыт до вызова open() тогда это ошибка, о которой сообщает ошибка потока. Не надо звонить open() если файл уже был открыт.

Обратите внимание, что вы можете создать файловый поток по умолчанию, чтобы вам не приходилось принимать решение о том, как открыть поток при создании.

std::fstream fs;

Это поток, который не имеет связанного файла, поэтому теперь вы можете вызвать open() с правильной семантикой.

должен быть указан двоичный режим?

Да, двоичный режим никогда не является режимом открытия по умолчанию. Если вам нужно, чтобы файл находился в двоичном режиме, необходимо указать эту опцию.

необходимо ли очистить поток перед последовательной записью?

Функция-член clear() предназначен для очистки маски ошибок, в которую можно записать данные из-за неудачного чтения / записи / и т. д. Только если есть ошибки, которые вы хотите очистить, это нормально. Но вам, вероятно, не нужно этого делать, поскольку вы просто открыли файл без каких-либо предварительных операций ввода-вывода.

было бы неправильно fs.close() сюда и не звони fs.open()

Вам обычно не нужно явно звонить close() если вы не хотите открыть новый файл в потоке. поскольку std::fstream это класс RAII, close() будет вызван в конце своей области (в конце основной).

Если вам нужно открыть новый файл, то вам следует позвонить close() сначала перед звонком open(),


Кроме того, предложение: если вы хотите, чтобы файл открывался в конце, то используйте std::ios_base::ate OpenMode:

if (choice == 1) {
    fs.open("file", ios_base::in | ios_base::binary | ios_base::ate);
    //                                                ^^^^^^^^^^^^^
    fs.write( (char *)&r, sizeof(r));
}
Другие вопросы по тегам