table of Contents
A Gentle Introduction to C++ IO Streams
Manasij Mukherjee
https://www.cprogramming.com/tutorial/c++-iostreams.html
One advantage of C ++ is its IO system, IO stream.
IO stream such that the following characteristics can be used various kinds of data management scenarios:
- Essence flow (stream) is a sequence of characters. Characters may be ordinary character (char) or wide character (wchat_t). Specific details stream provides a uniform character-based interface, the user does not need to learn to read and write to storage media of various types of storage medium (such as files). Any stream may be used as a write operation to the object can be written in any type of flow. In other words, as long as the object has a stream represented by the formula, any storage medium can receive this representation.
- Stream can be used built-in data types, and the user can insert operator (<<) by overloading (Overloading) and extraction operations (>>) to write or write to the stream of user-defined data types.
- Access to library functions in a unified way so that the flow is easy to use.
What do input and output really mean?
First, the information is understood as a character stream. The reason for this is understood, because no matter what we typed from the keyboard, can only be understood as a number of characters. Assume that the user typed numbers 7479. . . So, in fact, the programmer can not really know the user typed in the end is a digital keyboarding 7479 or that the four characters '7', '4', '7', '9'. Understand how they are completely up to the programmer, and whether these characters can be correctly understood as a type of programmer wants, depends entirely on whether the input stream of characters that can be target data type representation to understand.
Character input needs in an orderly way to store tissue, so that they can later be used as a variety of data types, unless they are just used as a character array.
IO streams not only defines the relationship between the characters and the annotation data stream type, allows the user to define relationships and custom character stream classes.
How do streams work?
Stream is a sequence of interface memory, cache files, and other storage media. The difference between the different storage media hidden beneath the interface.
For their interfaces, the serialized nature of the flow is very important. Users can not perform random read or write directly in the stream. Although it is possible seek
to specify the position of the reading and writing or the like.
Use serialized representation to all devices in a unified interface. Many devices have both production capacity and consumption data; if data is going production, then the easiest way to understand is to understand the read data stream to obtain the next character.
Closely integrated with the actual medium-level interface is character buffer (character buffer), it can be considered a core stream. As a buffer, if the data is too much, then it does not save all content streams and therefore can not be used for random access.
The basic operation is the focus of stream:
- First, the need to follow the flow of the appropriate data type (such as using
std::string
initializedstringstream
usingfilename
the initializationfstream
), an appropriate pattern (such as usingios::in
the initialization input) to initialize - After that, you can
get
orput
to clarify the position of the pointer IO operation takes place. Open flow depending on the position may have been set up (for example, if you useios::app
to open the file, thenget pointer
points to the end of the stream) - Once in the proper position in the stream, it is through the input and output
<<
and the>>
operator to complete.
Error handling with IO streams
An example of creating a stream-enable object
#include <ctime>
#include <fstream>
#include <iostream>
#include <sstream>
using namespace std;
std::string timestamp();
class LogStatement;
ostream& operator<<(ostream& ost, const LogStatement& ls);
class LogStatement {
public:
LogStatement(std::string s) : data(s), time_string(timestamp()) {}
friend ostream& operator<<(ostream& ost, const LogStatement&);
private:
std::string data;
std::string time_string;
};
ostream& operator<<(ostream& ost, const LogStatement& ls) {
ost << "~|" << ls.time_string << '|' << ls.data << "|~";
return ost;
}
std::string timestamp() {
ostringstream stream;
time_t rawtime;
tm* timeinfo;
time(&rawtime);
timeinfo = localtime(&rawtime);
stream << (timeinfo->tm_year) + 1900 << " " << timeinfo->tm_mon << " "
<< timeinfo->tm_mday << " " << timeinfo->tm_hour << " "
<< timeinfo->tm_min << " " << timeinfo->tm_sec;
return stream.str();
}
int main(int argc, char** argv) {
if (argc < 2) {
return -1;
}
ostringstream log_data;
for (int i = 1; i < argc; i++) {
log_data << argv[i] << ' ';
}
LogStatement log_entry(log_data.str());
clog << log_entry << endl;
ofstream logfile("logfile", ios::app);
if (!logfile) {
return -1;
}
logfile << log_entry << endl;
logfile.close();
return 0;
}
ostream
Is the base class for all write operations, such asofstream
andostringstream
. Standard stream object:std::cout
,std::cerr
,std::clog
and their width versions areostream
object classes.- Used
stringstream
to simplify the processing of the string
Parts of the IO stream library
Standard Stream Objects for Console IO:(cout, cin, clog, etc.)
These objects are declared in the <iostream>
header file, and provides a consistent interface for controlling the IO.
File IO
File IO is manually declare ifstream, ofstream or fstream
object classes and by using the stream open
to stream files and bind method.
#include <iostream>
#include <fstream>
using namespace std;
int main(){
ofstream ofs("a.txt", ios::app);
if(ofs.good())
{
ofs << "Hello a.txt, I'm appending this on you.";
}
return 0;
}
String Streams
Strings are streams and streams are strings. They are an array of characters, but they have completely different interfaces (random access strings vs serial stringstreams).
#include <iostream>
#include <sstream>
using namespace std;
int main()
{
stringstream my_stream(ios::in|ios::out);
std::string dat("Hey, I have a double : 74.79 .");
my_stream.str(dat);
my_stream.seekg(-7,ios::end);
double val;
my_stream>>val;
val= val*val;
my_stream.seekp(-7,ios::end);
my_stream<<val;
std::string new_val = my_stream.str();
cout<<new_val;
return 0;
}
The lower level, where streams meet buffers
his is the most interesting and confusing part of this library, letting you manipulate streams at their lowest levels, bytes and bits. This is achieved by the abstract base class streambuf
to achieve. stringbuf
And filebuf
are inherited from streambuf
. And each stream
object has one of them as their backbone. These objects have a function rdbuf()
, the function returns a pointer to the underlying stream buffer.
#include <iostream>
#include <fstream>
using namespace std;
int main(){
ifstream ifs("a.txt");
ofstream ofs("a.txt.copy", ios::trunc);
if(ifs && ofs){
ofs<<ofs.rdbuf();
}
return 0;
}