Simplify stream reading with line_as_stream

Source: Internet
Author: User

 


When you persist data to a file, you may find it difficult to force the system to write a specific part of the data to a row. Writing specific data to the same row is sometimes useful, for example, when you read an array from a stream (such as a file.

Suppose you want to read the elements of an array, and one row is damaged (for example, some data is lost ). In general, this will cause damage to all subsequent elements.

As an example, suppose we have a data structure, which is a window array and you want to persistently store it in a file, as shown below:

Row 1: Number of Windows
Each row following a window contains two values: the window width and the window height.
Writing code seems simple:

# Include
# Include
# Include

Struct Window
{
Window (int nLength = 0, int nHeight = 0)
: M_nWindowLength (nLength), m_n1_wheight (nHeight)
{}
Int m_nWindowLength;
Int m_n1_wheight;
};

Std: ostream & operator <(std: ostream & streamOut, const Window & value)
{
StreamOut <value. m_nWindowLength <"" <value. m_nWindowHeight;
Return streamOut;
}
Std: istream & operator> (std: istream & streamIn, Window & value)
{
StreamIn> value. m_nWindowLength> value. m_n1_wheight;
Return streamIn;
}

Void write_windows (std: vector <Window> & aWindows, const char * strFileName)
{
Std: ofstream streamOut (strFileName );
// The first line
StreamOut <aWindows. size () <std: endl;
// Other rows
Std: vector <Window >:: iterator itFirst = aWindows. begin (), itLast = aWindows. end ();
While (itFirst! = ItLast)
{
// The data of each window is in its own line
StreamOut <* itFirst <std: endl;
++ ItFirst;
}
}
However, to read the data correctly, there may be some problems:

// An error may occur !!!
Void read_windows (std: vector <Window> & aWindows, const char * strFileName)
{
AWindows. clear ();
Std: ifstream streamIn (strFileName );
Int nSize;
StreamIn> nSize;
For (int idx = 0; idx <nSize; ++ idx)
{
Window w;
StreamIn> w;
AWindows. push_back (w );
}
}

The above Code does not force anything. All data is put into a row, which seems to be okay. However, if you accidentally modify your file, insert a redundant value or delete a value, all the subsequent elements will get an incorrect value, and your program will not realize this. Run the following code in the notebook and take a closer look at the Annotations:

# Include
# Include
Int main (int argc, char * argv [])
{
Std: vector <Window> aWindows;
AWindows. push_back (Window (100,400 ));
AWindows. push_back (Window (200,400 ));
AWindows. push_back (Window (400,400 ));
AWindows. push_back (Window (500,500 ));
AWindows. push_back (Window (600,200 ));
AWindows. push_back (Window (600,400 ));
AWindows. push_back (Window (600,690 ));
Write_windows (aWindows, "persist.txt ");
Std: vector <Window> aReadWindows;
/* Add a debugging breakpoint here;
Modify persist.txt to delete the first value of row 4th */
Read_windows (aReadWindows, "persist.txt ");
Std: copy (aReadWindows. begin (), aReadWindows. end (),
Std: ostream_iterator <Window> (std: cout ,""));
/* Add a debugging breakpoint here: Check the number of errors you have read! */
Return 0;
}
Fortunately, you can use line_as_stream to read a row and regard it as a stream. Using this method, you can determine that each element is read from a row. Therefore, the read_windows function becomes like this:

Void read_windows (std: vector <Window> & aWindows, const char * strFileName)
{
AWindows. clear ();
Std: ifstream streamIn (strFileName );
Int nSize;
// The first line
Line_as_stream (streamIn)> nSize;
For (int idx = 0; idx <nSize; ++ idx)
{
Window w;
// The data of each window is in its own line
Line_as_stream (streamIn)> w;
AWindows. push_back (w );
}
}

Now, re-run the previous example and you can see that only one element is damaged, as expected.

This is the source code of line_as_stream:

# Include
# Include
# Include

Namespace Private
{
Template <class char_type, class char_traits>
Struct line_stream_holder
{
Typedef line_stream_holder <char_type, char_traits> this_class;
Typedef std: basic_istringstream <char_type, char_traits> stream_type;
Typedef std: basic_string <char_type, char_traits> string_type;
Line_stream_holder (const string_type & value)
: M_stream (value)
{}
Line_stream_holder (const this_class & source)
: M_stream (source. m_stream.str ())
{}

// Allow passing this stream in functions that
// Accept streams
Operator stream_type & () const
{Return m_stream ;}
Private:
Mutable stream_type m_stream;
};

Template <class char_type, class char_traits, class value_type>
Inline typename line_stream_holder <char_type, char_traits >:: stream_type & operator> (const line_stream_holder <char_type, char_traits> & streamIn, value_type & value)
{
Typedef typename line_stream_holder <char_type, char_traits >:: stream_type;
Stream_type & underlyingStream = streamIn;
UnderlyingStream> value;
Return underlyingStream;
}

} // Namespace Private

Template <class char_type, class char_traits>
Private: line_stream_holder <char_type, char_traits> line_as_stream (
Std: basic_istream <char_type, char_traits> & streamIn, char_type chDelim =)
{
Std: basic_string <char_type, char_traits> strLine;
Std: getline (streamIn, strLine, chDelim );
Return strLine;
}

Related Article

Contact Us

The content source of this page is from Internet, which doesn't represent Alibaba Cloud's opinion; products and services mentioned on that page don't have any relationship with Alibaba Cloud. If the content of the page makes you feel confusing, please write us an email, we will handle the problem within 5 days after receiving your email.

If you find any instances of plagiarism from the community, please send an email to: info-contact@alibabacloud.com and provide relevant evidence. A staff member will contact you within 5 working days.

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.