0

我有这个代码来序列化/反序列化类对象到文件,它似乎工作。但是,我有两个问题。

  1. 如果我想在我的班级中有一个和一个成员变量,而不是两个wstring(就像我现在一样)怎么办?(我认为在这种情况下我的代码不起作用?)。wstringstring
  2. 最后,在下面,主要是,当我初始化s2.product_name_= L"megatex";if 而不是 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;
}
4

1 回答 1

0

如果我想在我的类中有一个 wstring 和一个 string 成员变量,而不是两个 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;

提取器情况更复杂,因为您必须阅读 aswstring和转换为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使用 .将从文件中读取的 s(Unicode 格式)转换为strings locale

最后,在下面,主要是,当我初始化 s2.product_name_= L"megatex"; 如果我用俄语写了一些东西(例如,s2.product_name_= L"логин")而不是 megatex,则代码不再按预期工作。

wchar_t当你定义一个using的数组时,你L""并没有真正指定字符串是 Unicode,只是该数组是 chars,而不是 wchar_t。我想预期的工作是以s2.product_name_Unicode 格式存储名称,但编译器将获取char该字符串中的每个(没有L)并转换为wchar_t仅用零填充最重要的字节。在 C++11 之前,C++ 标准对 Unicode 的支持并不好(并且仍然不太受支持)。它仅适用于 ASCII 字符,因为它们在 Unicode(或 UTF-8)中具有相同的编码。

要在静态字符串中使用 Unicode 字符,您可以使用转义字符:\uXXXX. 我知道,对每个非英语角色都这样做并不是很舒服。您可以在 Web 的多个站点中找到 Unicode 字符列表。例如,在 Wikipedia 中:http ://en.wikipedia.org/wiki/List_of_Unicode_characters 。

于 2013-06-25T13:40:40.787 回答