使用流将类对象写入文件

时间:2013-06-25 12:59:07

标签: c++ string wofstream wifstream

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

  1. 如果改为两个wstring(就像我现在一样),我希望有一个wstring和一个string成员 我班上的变量? (我认为在这种情况下我的代码不起作用?)。
  2. 最后,在主要内容中,当我初始化s2.product_name_= L"megatex";而不是megatex我用俄语写的东西(例如,s2.product_name_ = L“логин”)时,代码不再按预期工作
  3. 有什么不对?感谢。

    这是代码:

    // 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;
    }
    

1 个答案:

答案 0 :(得分:0)

  

如果改为两个wstring(就像我现在的那样)我想拥有一个   wstring和我班上的一个字符串成员变量? (我想是这样的   我的代码不起作用?)。

为任何char *basic_ostreamostream)定义了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)进行输出,那就没问题。

否则,您需要处理locale s。 locale提供文化上下文信息来解释字符串(记住这只是一个字节序列,而不是字母或符号意义上的字符;字节和符号代表的映射由locale定义)。 locale不是一个非常容易使用的概念(人类文化也不是这样)。正如你自己建议的那样,最好先调查一下它是如何运作的。

无论如何,这个想法是:

  1. 识别字符串中使用的字符集和文件中使用的字符集(Unicode或utf-16)。
  2. 使用stringlocale从原始字符集转换为Unicode以进行输出。
  3. 使用wstringstring的读取文件(使用Unicode)转换为locale
  4.   

    最后,在main中,当我初始化s2.product_name_ =时   L “MEGATEX”;如果不是megatex我用俄语写一些东西说   (例如,s2.product_name_= L"логин"),代码不再起作用   意图。

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

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