2015-08-23 2 views
0

Я работаю над проектом уровня начинающего уровня C++ (не абсолютным новичком, как «что такое цикл», но я бы не сказал, что это тоже средний уровень).C++: записать значения в файл самым простым и чистым способом?

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

Я немного читал о таких параметрах, как сериализация, используя некоторые нестандартные библиотеки и т. Д. Но мне нужно держать его максимально простым и чистым.

До сих пор у меня есть 2 структур, в значительной степени, как это:

struct client { 
    string name; 
    string address; 
    double phone; 
}; 
struct invoice { 
    string client_name; 
    double total; 
}; 

Я ищу что-то вроде этого примера, приведенного в http://www.cplusplus.com/doc/tutorial/files:

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

int main() { 
    ofstream myfile; 
    myfile.open ("example.txt"); 
    myfile << "Writing this to a file.\n"; 
    myfile.close(); 
    return 0; 
} 

Есть ли способ сделать что-то как писать, но писать (а затем читать) структурные переменные в файл, сохраняя его простым? Несколько лет назад я помню об этом очень просто в Pascal при записи записей в файлы. Это было что-то вроде: открыть файл, записать поле записи 1, написать поле separador, записать поле записи 2, разделитель поля записи, разделитель записи записи. Затем, читая, я буду искать разделители. Это не рекомендуется в C++?

Спасибо.

+2

Да, это может быть сделано. Должны ли мы изобрести структуру, или вы покажете нам свою? – Beta

+5

Чтобы ответить на этот вопрос, вы действительно хотите сказать, что находится в ваших «структурных переменных». Не все структурные переменные могут быть прочитаны или написаны одинаково. – john

+0

Лучшей отправной точкой будет http://www.cplusplus.com/doc/tutorial/basic_io/. –

ответ

2

Вы можете проверить сериализацию для C++, например. Boost :: сериализация в библиотеке Boost.

Is it possible to serialize and deserialize a class in C++?

+4

Ссылка только ответы плохие, и на самом деле есть больше вариантов, помимо синтаксиса. Если вы считаете, что вопрос является дубликатом, отметьте его как таковой, вместо того, чтобы дать ответ. –

+0

Я не знал об этом, попытаюсь сделать это в следующий раз. Похоже, я должен прочитать некоторые часто задаваемые вопросы, связанные с ответом! Спасибо, что заметили! – SCO

1

Вы должны связать 2 функции в этом классе: inputStruct и OutputStruct. Ввод должен быть в состоянии прочитать, что выводит. Легкий способ заключается в написании каждого элемента структуры в том же порядке, в котором они реализованы.

1

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

С помощью C++ вы можете перегрузить поток оператора, поэтому он будет выглядеть довольно в вашем коде, но на других языках вы должны использовать для этого функции.

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

UPDATE:

Я сделал сериализации и десериализации функции. Я их не тестировал, поэтому я не уверен, что они будут работать на 100%.

Статические функции:

void serialize_client(ofstream& out, client& cl) 
{ 
    out << cl.name << endl; 
    out << cl.address << endl; 
    out << cl.phone << endl; 
} 

void deserialize_client(ifstream& in, client& cl) 
{ 
    getline(in, cl.name); 
    getline(in, cl.address); 
    in >> cl.phone;  
} 

Использование:

client client_instance; 
deserialize_client(cin, client_instance); 
serialize_client(cout, client_instance); 

С перегрузкой оператора:

ostream& operator<<(ostream& os, const client& cl) 
{ 
    os << cl.name << endl; 
    os << cl.address << endl; 
    os << cl.phone << endl; 
    return os; 
} 

istream& operator>>(istream& is, client& cl) 
{ 
    getlise(is, cl.name); 
    getlise(is, cl.address); 
    is >> cl.phone; 
    return is; 
} 

client client_instance; 
cin >> client_instance; 
cout << client_instance; 
+0

Спасибо за информацию :) Однако данные не будут отправляться по сети (это настольная программа, которая работает только на одном компьютере). Однако мне нужна программа для работы на разных компьютерах. Должен ли я в этом случае заниматься сериализацией? – Floella

+1

Вы можете сериализовать данные в текстовый файл, в этом случае у вас не будет проблем с контентом, но он использует больше памяти. Если вы сериализуете в двоичный файл, вы должны иметь дело с контентом. –

+0

Спасибо :) Я бы предпочел использовать больше памяти, чем заниматься контентом. О вашем коде: где бы я установил имя файла, если я выбираю статические функции (без перегрузки оператора)? Должен ли я объявлять объекты 'std :: ifstream in' и' std :: outstream out' перед вызовом функций? Кроме того, я немного смущен, почему вы передаете cin и cout в качестве аргументов при вызове функций. Еще раз спасибо за помощь :) – Floella