Click here to Skip to main content
15,923,051 members
Please Sign up or sign in to vote.
0.00/5 (No votes)
See more:
I have this code to serialize/deserialize class objects to file, and it seems to work.
However, I have two questions.

1. What if instead two wstring's (as I have now) I want to have one wstring and one string member
variable in my Product class? (I think in such case my code won't work?).

2. Finally, below, in main, when I initialize s2.product_name_= L"megatex"; if instead of megatex I write something in Russian say (e.g., s2.product_name_= L"логин"), the code doesn't work anymore as intended.

What can be wrong? Thanks.

Here is code:
C++
// 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; // error 1
    }

    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_); // error 5, also error 2

        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;
}
Posted
Updated 25-Jun-13 20:42pm
v2
Comments
nv3 25-Jun-13 11:14am    
Can you show the compilation errors you get when you use string instead of wistream? I assume they are with the getline calls?

And what exactly goes wrong when you assign a cyrillic string to your product name?
Dan page 26-Jun-13 2:22am    
This is one error:

- (from operator <<) Error 1 error C2679: binary '<<' : no operator found which takes a right-hand operand of type 'const std::string' (or there is no acceptable conversion)

this is second:

- Error 5 error C2780: 'std::basic_istream<_Elem,_Traits> &std::getline(std::basic_istream<_Elem,_Traits> &&,std::basic_string<_Elem,_Traits,_Alloc> &,const _Elem)' : expects 3 arguments - 2 provided

The above one is related to getline
Sergey Alexandrovich Kryukov 26-Jun-13 2:31am    
In what lines? Don't put it in comments. Use "Improve question" and add comments to the code next to the offending lines...
—SA
Dan page 26-Jun-13 2:43am    
like this?

ps. this is error2:

Error 2 error C2782: 'std::basic_istream<_Elem,_Traits> &std::getline(std::basic_istream<_Elem,_Traits> &,std::basic_string<_Elem,_Traits,_Alloc> &)' : template parameter '_Elem' is ambiguous c:\users\documents\visual studio 2012\projects\consoleapplication3\consoleapplication3\consoleapplication3.cpp 34 1 ConsoleApplication3

some other parts of code I managed to modify. I get two or three other errors to but they are same as I posted above, and at same lines.
Sergey Alexandrovich Kryukov 26-Jun-13 2:45am    
Why you don't want to do what I suggested?
—SA

1 solution

First of all, you can mix wstring and string (why not, in principle?), but you don't have to, because you can have the following universal approach: convert all kinds of strings to array of bytes using UTF-8 Unicode encoding. This encoding codes a code point below 256 as one byte, and pack others in 2-4 byte words when it is required by its algorithm. This way, you would have universal persistence method for all strings.

I would advice to look at the comprehensive way of C++ object persistence: boost serialization: http://www.boost.org/doc/libs/1_53_0/libs/serialization/doc/index.html[^].

[EDIT]

In response to the follow-up question:

Before you can move any further, you really need to learn more about Unicode:
http://en.wikipedia.org/wiki/Unicode[^],
http://en.wikipedia.org/wiki/Code_point[^],
http://en.wikipedia.org/wiki/Utf-8[^],
http://en.wikipedia.org/wiki/Byte_order_mark[^],
http://unicode.org/[^],
http://www.unicode.org/faq/utf_bom.html[^].

If you have any questions on these topics, you are welcome to ask, but I expect you to learn general concepts by yourself first.

—SA
 
Share this answer
 
v3
Comments
Dan page 25-Jun-13 10:36am    
>>"First of all, you can mix wstring and string (why not, in principle?)"
Hi, because if I declare one of my wstrings above as a string, I get compilation errors.

>>"convert all kinds of strings to array of bytes using UTF-8 Unicode encoding. "
Can you explain a bit more details on this how? and also bit more information on the second part of your first paragraph.
Sergey Alexandrovich Kryukov 25-Jun-13 10:45am    
Well, fix the compilation error first, this is way easier then persistence... :-)
It is not related to your problem at all.
—SA
Dan page 25-Jun-13 10:52am    
It's not easy to fix those issues, that's the problem ...
Sergey Alexandrovich Kryukov 25-Jun-13 16:04pm    
Well, add a comment to the exact line which causes compilation error, add complete error information, let's see...
—SA
Dan page 26-Jun-13 2:23am    
I posted errors above, below nav3's comment

This content, along with any associated source code and files, is licensed under The Code Project Open License (CPOL)



CodeProject, 20 Bay Street, 11th Floor Toronto, Ontario, Canada M5J 2N8 +1 (416) 849-8900