C++ Streams
Intro: Link
What is stream?: Serial IO Interferface to external devices (file, stdin/stdout, network, etc.)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
string s("Hello");
s[3] = 't'; // Random access
//cout[3] = 't'; // Error
{
ofstream of("MyLog.txt"); // Creates a new file for write, if the file didn't exist
of << "Text" << endl;
of << 234 <<endl;
of << 2.3 <<endl;
of << bitset<8>(14) << endl; // 00001110
of << complex<int>(2,3) << endl; // (2,3)
} //RAII
IO Operations:
formatting the data <——–> communicatiing the data with external devices
Software Engineer Principle: Low Couping -> Resuability
File Stream and Error Handling: Link
Ouput:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
{
ofstream of("Log.txt");// Open file for write , and clear the file
cout<< "Text to the file"<< endl;
}
{
ofstream of("Log.txt", ofstream::app); // Move the output pointer to te end of the file
cout<< "Text to the file"<< endl;
}
{
ofstream of("Log.txt", ofstream::in | ofstream::out);
of.seekp(10, ios::beg); // Move the output pointer 10 chars after begin
of << "12345"; // Overwrite 5 char
of.seekp(-5, ios::end); //Move the output pointer 5 chars before end
of << "More text, more text" << endl;
of.seekp(-5, ios::cur); // Move the ouput pointer 5 char before the current position
}
Input:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
{
ifstream inf("Log.txt");
int i;
inf >> i; // read one word
// Error status: goodbit, badbit, failbit, eofbit
inf.good(); // Everything is OK (goodbit = 1)
inf.bad(); //Non-recoverable error (badbit = 1)
inf.fail(); //Failed Stream operation (failbit == 1 badbit == 1)
inf.eof(); // End of file (eofbit == 1)
inf.clear(); // Clear all error status
inf.clear(ios::badbit); // sets a new value to the error flag
inf.rdstate(); // Read the current status flag
inf.clear(inf.rdstate() & ~ios::failbit); // Clear only the failbit
if(inf) // Equivalent to: if (!inf.fail())
cout << "Read successfully"
if(inf >> i)
cout << "Read successfully";
// Handle the errors with exceptions
inf.exceptions(ios::badbit | ios::failbit); // setting the exception mask
// When badbit or failbit set 1, exception of iosLLfailure will be thrown
// When eofbit set to 1, no exception
inf.exceptions(ios::goodbit); // No exception
}
Formatted and Unformatted IO: Link
Formatting IO
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
cout << 34 << endl; //34
cout.setf(ios::oct, ios::basefield);//ocatal
cout << 34; // 42
cout.setf(ios::showbase);
cout << 34; // 042
cout.setf(ios::hex, ios::basefield);
cout <<34; // 0x22
cout.unsetf(ios::showbase);
cout << 34; // 22
cout.setf(ios::dec, ios::basefield);
cout.width(10);
cout << 26 << endl; // 26
cout.setf(ios::left, ios::adjustfield); //26
// Floating points values
cout.setf(ios::scientific, ios::floatfield);
cout << 340.1 << endl; // 3.401000e+002
cout.setf(ios::fixed, ios::floatfield);
cout << 340.1 << endl; //340.100000
cout.precision(3)l
cout << 340.1 << endl; //340.100
int i;
cin.setf(ios::hex, ios::basefield);
cin >> in // Enter: 12
//i==18
ios::fmtflags f = cout.flags(); //Current flags been used
cout.flags(ios::oct | ios::showbase);
cout.flags(); // returns ios::oct | ios::showbase
Unformated IO
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
ifstream inf("Log.txt");
char buf[80];
inf.get(buf,80); // read up to 80 chars and save to buf
inf.getLine(buf, 80); //readu up to 80 or until a '\n'
inf.read(buf, 80); // read 80 chars
inf.ignore(3);
inf.peek();
inf.unget(); // return a char back to the stream( retuns same last char)
inf.putback('z'); //returns a char 'z' to the stream
inf.get();
inf.gcount(); // return the number of chars being read bu last unformatted read
//output
ofstream of("Log.txt");
of.put('c');
of.write(buf, 6); // write first 6 chars of buf
of.flush(); // Flush output to screen in case of cout
Manipulators: Link
Descriptions: In this video Bo Qian explains what are manipulators by using an example that is well know std::endl
. A brief description concludes that endl is a fucntion that manipulates the stream.
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
ostream& endl(ostream& sm){ // Manipulator
sm.put('\n');
sm.flush();
return sm;
}
ostream& ostream::operator<<(ostream& (*func)(ostream&)){
return (*func)(*this);
}
int main(){
cout << "hello" << endl; //endl: '\n' and flush
// object? Build-in data type? function? (look to func above)
// More manipulators
cout << ends; //'\0'
cout << flush;
cin >> ws; // read and discard white spaces
cout << setw(8) << left << setfill('_') << 99 << endl; //99______
cout << hex << showbase << 14; //0xe
// More in: https://www.cplusplus.com/reference/ios/
}
Stream Buffer: Link
IO Operations:
- Formating data – stream
- Communicating data to external devices – stream buffer
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
cout << 34; //Formatting
streambuf* pbuf = cout.rdbuf();
ostream myCout(pbuf);
myCout.setf(ios::showpos);
myCout.width(20);
myCout << 12 << endl; // +12
cout << 12 << endl; //12
//Redirecting
ofstream of("Log.txt");
streambuf* oriBuf = cout.rdbuf(); // saving backup from original
cout.rdbuf(of.rdbuf());
cout << "Hello" << endl; // Log.txt has "Hello"
cout.rdbuf(oriBuf); // setting cout to original buffer
cout << "Bye" << endl; //stdout: Bye
//Stream buffer iterator
istreambuf_iterator<char> i(cin);
ostreambuf_iterator<char> o(cout);
// Copy
while(*i != 'x'){
*o = *i;
++o;
++i;
} // exit option if press x
//Similar to copy with no exit
copy(istreambuf_iterator<char>(cin), istreambuf_iterator<char>(), ostreambuf_iterator<char>(cout));
String Stream : Link
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
// Srtring Stream
stringstream ss; // Stream without IO operation
// read/write of string
// Example
ss << 89 << " Hex: " << hex << 89 << " Oct: " << oct << 89;
cout << ss.str() << endl; //89 Hex: 59 Oct: 131
int a, b, c;
string s1;
ss << hex >> a; // Formatted input works token by token, spaces, tabs, newlines
//a == 137
ss >> s1; // s1: "Hex:"
ss >> dec >> b; //b==59
ss.ignore(6);
ss>> oct >> c; //c==89
Recommendation: stringstream
is used in the example above for input and output but this fucntionality is also offered by two other stream class.
ostringstream
: Used only for formatted outputistringstream
: Used only for formatted input
It is recommended for readibility that we use the streams mention above, because they portray our intention for the given stream.
Enable Streaming for Your Own Class: Link
Description: Class of Dog
allows for IO Stream creating and outputing formatted data.
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
using namespace std;
//Creating Stream-enabled Class
struct Dog{
int age_;
string name_;
};
// Input Stream
ostream& operator<<(ostream& sm, const Dog& d){
sm << "My name is " << d.name_ << " and my age is " << d.age_ << endl;
return sm;
}
// Output Stream
istream& operator>>(istream& sm, Dog& d){
sm >> d.age_;
sm >> d.name_;
return sm;
}
int main(){
Dog d{2, "Bob"}; // Universal Initialization from c++11
cout << d;
cin >> d; // 5 carl [Input]
cin << d; //My name is carl and my age is 5 [Output]
}