Вопрос:

В чем разница между ios :: app, out и trunc в c ++?

c++

4829 просмотра

2 ответа

129 Репутация автора

Я знаю, что режим открытия файла по умолчанию отсутствует . И я думаю , что данные будут перезаписаны в файле, но в следующем коде данные о возрасте не перезаписывают данные об именах .

#include <fstream> 
#include <iostream> 
using namespace std;

int main () {

    char data[100];

    // open a file in write mode.
    ofstream outfile;
    outfile.open("afile.dat");

    cout << "Writing to the file" << endl; 
    cout << "Enter your name: ";
    cin.getline(data, 100);

    // write inputted data into the file.
    outfile << data << endl;

    cout << "Enter your age: "; 
    cin >> data; 
    cin.ignore();

    // again write inputted data into the file.
    outfile << data << endl;
    // close the opened file.
    outfile.close();

    // open a file in read mode.
    ifstream infile; 
    infile.open("afile.dat");

    cout << "Reading from the file" << endl; 
    infile >> data;

    // write the data at the screen. 
    cout << data << endl;

    // again read the data from the file and display it. 
    infile >> data; 
    cout << data << endl;

    // close the opened file.
    infile.close();

    return 0;

Тогда я запутался в трех режимах открытия файла - app, out, trunc.

Если для имени я ввожу «Zara» и возраст «9», вывод должен быть «9ara». Однако это не так. Это «Зара 9».

Автор: user67265 Источник Размещён: 03.01.2018 10:01

Ответы (2)


10 плюса

455043 Репутация автора

ios::outявляется режимом по умолчанию для std::ofstream, это означает, что могут быть использованы выходные операции (т.е. вы можете записать в файл).

ios::app(сокращение от добавления ) означает, что вместо перезаписи файла с самого начала все операции вывода выполняются в конце файла. Это имеет смысл, только если файл также открыт для вывода.

ios::trunc(сокращение от truncate ) означает, что при открытии файла старое содержимое немедленно удаляется. Опять же, это имеет смысл, только если файл также открыт для вывода.

Ваш код просто использует ios::outрежим по умолчанию . Таким образом, он начинает запись с начала файла, но не удаляет старое содержимое. Таким образом, новое содержимое будет перекрывать то, что уже есть - если файл изначально имеет длину 10 байт, и вы записываете 3 байта, то результатом будут 3 записанных вами байта, за которыми следуют оставшиеся 7 байтов исходного содержимого. Конкретнее, если файл изначально содержит:

Firstname Lastname
30

и вы пишете, FN LNа затем 20(с символами новой строки после каждого), получившийся файл будет выглядеть так:

FN LN
20
 Lastname
30

потому что вы перезаписываете только первые 9 байтов файла (при условии перевода строки в стиле Unix).

После того как вы открыли файл, все выходные данные в файл записываются последовательно друг за другом, если вы не используете outfile.seekp()для перехода в другое место. Он не возвращается к началу файла для каждой вещи, которую вы пишете. seekp()не имеет никакого эффекта, если ios::appиспользуется; тогда каждая запись идет в конец файла.

Автор: Barmar Размещён: 03.01.2018 10:24

1 плюс

18 Репутация автора

Просто небольшое исправление к ответу Бармара. Я думаю, что тип потока подразумевает не только ios :: out, но также ios :: trunc (и я не уверен, но ios :: out также может подразумевать ios :: trunc).

Вот конкретный пример:

ofstream fich;
    fich.open("archivo.txt");
    for (unsigned i = 0; i < ag.n_pers && !fich.fail(); ++i) {
        escribir_persona(fich, ag.pers[i]);
    }
    if (fich.fail()) {
        ok = ERROR;
    }
    else {
        ok = OK;
    }
    fich.close();

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

Автор: Inot Размещён: 01.10.2018 06:23
Вопросы из категории :
32x32