Запись объекта класса в файл с использованием потоков

У меня есть этот код для сериализации / десериализации объектов класса в файл, и, похоже, работает.
Однако у меня есть два вопроса.

  1. Что делать, если вместо двух wstring‘s (как у меня сейчас) я хочу иметь один wstring и один string член
    переменная в моем классе? (Я думаю, что в таком случае мой код не будет работать?).
  2. Наконец, ниже, в основном, когда я инициализирую s2.product_name_= L"megatex"; если вместо мегатекса я напишу что-нибудь на русском языке, скажем (например, s2.product_name_ = L «логин»), код больше не будет работать так, как задумано.

Что может быть не так? Благодарю.

Вот код:

// ConsoleApplication3.cpp : Defines the entry point for the console application.
//

#include "stdafx.h"#include <iostream>
#include <string>
#include <fstream>      // std::ifstream
using namespace std;

// product
struct Product
{
double price_;
double product_index_;
wstring product_name_;
wstring other_data_;

friend std::wostream& operator<<(std::wostream& os, const Product& p)
{
return os << p.price_ << endl
<< p.product_index_ << endl
<< p.product_name_ << endl
<< p.other_data_ << endl;
}

friend wistream& operator>>(std::wistream& is, Product& p)
{
is >> p.price_ >> p.product_index_;
is.ignore(std::numeric_limits<streamsize>::max(), '\n');

getline(is,p.product_name_);
getline(is,p.other_data_);

return is;
}
};

int _tmain(int argc, _TCHAR* argv[])
{
Product s1,s2;

s1.price_ = 100;
s1.product_index_ = 0;
s1.product_name_= L"flex";
s1.other_data_ = L"dat001";

s2.price_ = 300;
s2.product_index_ = 2;
s2.product_name_= L"megatex";
s2.other_data_ = L"dat003";

// write
wofstream binary_file("c:\\test.dat",ios::out|ios::binary|ios::app);
binary_file << s1 << s2;
binary_file.close();

// read
wifstream binary_file2("c:\\test.dat");

Product p;
while (binary_file2 >> p)
{
if(2 == p.product_index_){
cout<<p.price_<<endl;
cout<<p.product_index_<<endl;
wcout<<p.product_name_<<endl;
wcout<<p.other_data_<<endl;
}
}

if (!binary_file2.eof())
std::cerr << "error during parsing of input file\n";
else
std::cerr << "Ok \n";

return 0;
}

0

Решение

Что если вместо двух wstring (как у меня сейчас) я хочу иметь один
wstring и одна строковая переменная-член в моем классе? (Думаю в такой
если мой код не будет работать?).

Есть определитель, определенный для char * для любого basic_ostream (ostream а также wostream), так что вы можете использовать результат c_str() вызов функции-члена для string член. Например, если string участник other_data_:

 return os << p.price_ << endl
<< p.product_index_ << endl
<< p.product_name_ << endl
<< p.other_data_.c_str() << endl;

Случай экстрактора является более сложным, так как вам придется читать как wstring и преобразовать в string, Самый простой способ сделать это просто читать как wstring а затем сужение каждого символа:

wstring temp;
getline(is, temp);
p.other_data_ = string(temp.begin(), temp.end());

Я не использую локали в этом примере, я просто преобразовываю последовательность байтов (8 бит) в последовательность слов (16 бит) для вывода и противоположных (усеченных значений) для ввода. Это нормально, если вы используете символы ASCII или однобайтовые символы и вам не требуется определенный формат (например, Unicode) для вывода.

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

Во всяком случае, идея заключается в следующем:

  1. Определите кодировку, используемую в строке, и кодировку, используемую в файле (Unicode или utf-16).
  2. Преобразовать strings из оригинальной кодировки в Unicode, используя locale для вывода.
  3. Преобразовать wstringчитать из файла (в Unicode) в stringс помощью locale,

Наконец, ниже, в основном, когда я инициализирую s2.product_name_ =
L «Мегатекс»; если вместо мегатекса я напишу что нибудь по русски скажу
(например., s2.product_name_= L"логин"), код больше не работает, так как
предназначена.

Когда вы определяете массив wchar_t с помощью L""вы на самом деле не указываете, что строка является Unicode, просто массив состоит из символов, а не wchar_t. Я предполагаю, что предполагаемая работа s2.product_name_ хранить имя в формате Unicode, но компилятор будет принимать все char в этой строке (как без L) и преобразовать в wchar_t просто заполнение нулями самого значимого байта. Юникод не очень хорошо поддерживается в стандарте C ++ до C ++ 11 (и все еще не слишком поддерживается). Это работает только для символов ASCII, потому что они имеют одинаковую кодировку в Unicode (или UTF-8).

Для использования символов Unicode в статической строке вы можете использовать escape-символы: \uXXXX, Я знаю, что делать это для каждого неанглийского персонажа не очень удобно. Вы можете найти список символов Unicode на нескольких сайтах в Интернете. Например, в Википедии: http://en.wikipedia.org/wiki/List_of_Unicode_characters.

0

Другие решения

Других решений пока нет …

По вопросам рекламы [email protected]