A stream is an abstraction for input/output. You can think of it as a source (input) or destination (output) of characters of indefinite length.
C++ provides a header filed called <fstream>
(file stream) that exports the ifstream
and ofstream
types, streams that perform file I/O. Input/output stream class to operate on files.
Objects of this class maintain a filebuf object as their internal stream buffer, which performs input/output operations on the file they are associated with (if any).
#include <fstream> // std::fstream
std::fstream fs;
fs.open ("iofiles/test.txt", std::fstream::in | std::fstream::out | std::fstream::app);
fs << "More lorem ipsum...."; // write to the created file
fs.close(); // Close the stream
!cd iofiles && ls && cat test.txt
test.txt More lorem ipsum....
fs.open ("iofiles/test.txt", std::fstream::in | std::fstream::out | std::fstream::app); // Re-open the stream
fs << "Last but not the least lorem ipsum!!"; // Write some more to the file
fs.close(); // Close the stream
!cd iofiles && ls && cat test.txt
test.txt More lorem ipsum....Last but not the least lorem ipsum!!
setw
manipulator do?¶setw(n)
sets the minimum width of the input for the next stream operation. If the data doesn't meet the minimum field requirement, it is padded with the default fill character until it is proper size.
#include <iostream>
std::cout << "Output: " << 10 << std::endl;
Output: 10
std::cout << "Output: " << std::setw(5) << 10 << std::endl;
Output: 10
boolalpha
manipulator do?¶boolalpha
determines whether or not the stream should output boolean values as 1 and 0 or as "true" and "false". The opposite manipulator is noboolalpha
, which reverses this behaviour.
std::cout << true << std::endl;
1
std::cout << std::boolalpha<< true << std::endl;
true
hex
, dec
, oct
manipulator do?¶They set the radix on the stream to either octal (base 8), decimal (base 10), or hexadecimal (base 16). This can be used either to format output or change the base for input.
std::cout << 10 << std::endl;
10
std::cout << std::dec << 10 << std::endl;
10
std::cout << std::oct << 10 << std::endl;
12
std::cout << std::hex << 10 << std::endl;
a
Because stream operations often involved transforming data from one form into another, stream operations are not always guaranteed to succeed.
Let's use the previously created test.txt
file to demonstrate stream failure.
For the following program:
test.txt
contains NUM_INTS
consecutive integer values, then this code will work correctly.To check if a stream is in an erroneous state, we use the .fail()
member function.
#include <fstream>
fs.open ("iofiles/test.txt", std::fstream::in | std::fstream::out | std::fstream::app);
int NUM_INTS = 5;
for(int i = 0; i < NUM_INTS; i++){
int value;
fs >> value;
/*..... Do something Here ....*/
if(fs.fail()) break;
std::cout << value << std::endl;
}
As you can see, when the program realizes that the file contains text and not integers, it breaks out of the loop without doing any subsequent operation.
stringstream
?¶In C++, you can't add numbers to strings and when you can, it's almost certainly won't do what you expected.
One solution to this problem is to use another kind of stream object known as a stringstream
, exported by <sstream>
header. Like console streams and file streams, stringstreams are stream objects. Instead of reading or writing data to an external source, stringstreams store data in temporary string buffers.
#include <sstream> // std::stringstream, std::stringbuf
std::stringstream ss;
ss << "Hello World! It's " << 135 << std::endl;
Once you have put data into a stringstream, you can retrieve the string you have created using the .str()
member function.
std::string s = ss.str();
std:: cout << s << std::endl;
Hello World! It's 135
stringstreams are an example of an iostream, a stream that can perform both input and output, You can both insert data inot a stringstream to convert the data to string and extract data from a stringstream to convert string data into a different format. For example:
std::stringstream myConverter;
int myInt;
std::string myString;
double myDouble;
std::cout << myInt << std::endl;
std::cout << myString << std::endl;
std::cout << myDouble << std::endl;
0 0
myConverter << "5 World 3.14"; // Insert string data
myConverter >> myInt >> myString >> myDouble; // Extract mixed data
std::cout << myInt << std::endl;
std::cout << myString << std::endl;
std::cout << myDouble << std::endl;
5 World 3.14
int
into a string
¶std::string intToStr(int myInt){
std::stringstream ss;
ss << myInt;
std::string s = ss.str();
return s;
}
std::string str = intToStr(5);
std::cout << str << std::endl;
5
void DrawTriangle(int numRows){
for(int i = 1 ; i <= numRows; i++) {
//Print a field of spaces equal to the number of rows minus half the width of the triangle, plus 2 spaces
//between the row number and the triangle,
std::cout << std::setfill(' ') << std::setw(numRows - i + 2) << " ";
//Print a field of pipes equal to the number of row number*2 then subtract 1 to keep the width odd and centered.
std::cout << std::setfill('#') << std::setw((i * 2 - 1)) << "#";
std::cout << std::endl;
}
}
DrawTriangle(5)
# ### ##### ####### #########
DrawTriangle(8)
# ### ##### ####### ######### ########### ############# ###############
DrawTriangle(15);
# ### ##### ####### ######### ########### ############# ############### ################# ################### ##################### ####################### ######################### ########################### #############################