Как записать объект зарегистрировать в C++

У меня есть объект с несколькими текстовыми строками как участники. Я хочу записать этот объект в файл внезапно, вместо того, чтобы писать каждую строку в файл. Как я могу сделать это?

12
задан neuromancer 4 March 2010 в 00:59
поделиться

7 ответов

Вы можете переопределить оператор >> и оператор << для чтения / записи в поток.

Пример Entry struct с некоторыми значениями:

struct Entry2
{
    string original;
    string currency;

    Entry2() {}
    Entry2(string& in);
    Entry2(string& original, string& currency)
        : original(original), currency(currency)
    {}
};


istream& operator>>(istream& is, Entry2& en);
ostream& operator<<(ostream& os, const Entry2& en);

Реализация:

using namespace std;

istream& operator>>(istream& is, Entry2& en)
{
    is >> en.original;
    is >> en.currency;
    return is;
}

ostream& operator<<(ostream& os, const Entry2& en)
{
    os << en.original << " " << en.currency;
    return os;
}

Затем вы открываете файловый поток и для каждого вызываемого объекта:

ifstream in(filename.c_str());
Entry2 e;
in >> e;
//if you want to use read: 
//in.read(reinterpret_cast<const char*>(&e),sizeof(e));
in.close();

Или выводите:

Entry2 e;
// set values in e
ofstream out(filename.c_str());
out << e;
out.close();

Или, если вы хотите используйте поток , чтение и запись , тогда вы просто заменяете соответствующий код в реализации оператора .

Когда переменные являются закрытыми внутри вашей структуры / класса, вам необходимо объявить operator как дружественные методы.

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

10
ответ дан 2 December 2019 в 06:44
поделиться

На самом деле нет простого способа, в конце концов, это C ++, а не PHP или JavaScript.

http://www.parashift.com/c++-faq-lite/serialization.html

Boost также имеет для этого некоторую библиотеку: http://www.boost.org/doc/libs/ release / libs / serialization ... как уже упоминалось в Tronic :)

1
ответ дан 2 December 2019 в 06:44
поделиться

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

Вы можете использовать Boost.Serialization, чтобы минимизировать количество кода, необходимого для правильной переносимой и версионной поисковой идентификации.

0
ответ дан 2 December 2019 в 06:44
поделиться

Предполагая, что ваша цель такая, как указано, чтобы записать объект с помощью одного вызова write () или fwrite () или чего-то еще, вам сначала нужно скопировать строку и другие данные объекта в один непрерывный блок памяти. . Затем вы можете записать () этот блок памяти одним вызовом. Или вы можете выполнить векторную запись, вызвав writev (), если этот вызов доступен на вашей платформе.

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

0
ответ дан 2 December 2019 в 06:44
поделиться

Это называется сериализация. На SO есть много тем по сериализации.

Есть также хорошая библиотека сериализации, включенная в boost.

http://www.boost.org/doc/libs/1_42_0/libs/serialization/doc/index.html

в основном вы можете делать

myFile<<myObject 

и

myFile>>myObject

с помощью сериализации boost.

6
ответ дан 2 December 2019 в 06:44
поделиться

Если у вас есть:

struct A {
    char a[30], b[25], c[15];
    int x;
}

то вы можете записать все это просто с помощью write(fh, ptr, sizeof(struct a))

Конечно, это не переносимо (потому что мы не сохраняем конечность или размер "int", но это может не быть проблемой для вас.

Если у вас есть:

struct A {
    char *a, *b, *c;
    int d;
}

то вы не хотите записывать объект; вы хотите его сериализовать. Вам лучше всего обратиться к библиотекам Boost и использовать их процедуры сериализации, потому что это непростая проблема в языках без рефлексии.

5
ответ дан 2 December 2019 в 06:44
поделиться

Лучший метод - записывать каждое поле отдельно вместе с длиной строки.

В качестве альтернативы можно создать массив char (или std::vector) и записать все члены в буфер, затем записать буфер на вывод.

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

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

Другие люди посоветуют посмотреть библиотеку Boost Serialization.

1
ответ дан 2 December 2019 в 06:44
поделиться
Другие вопросы по тегам:

Похожие вопросы: