Learn About Input and Output in C++

01
of 08

A New Way to Output

Program code
traffic_analyzer/Getty Images

C++ retains very high backwards compatibility with C, so <stdio.h> can be included to give you access to the printf() function for output. However, the I/O provided by C++ is significantly more powerful and more importantly type safe. You can still also use scanf() for input but the type safety features that C++ provides means that your applications will be more robust if you use C++.

In the previous lesson, this was touched on with an example that used cout. Here we'll go into a bit more depth starting with output first as it tends to be more used than input.

The iostream class provides access to the objects and methods you need for both output and input. Think of i/o in terms of streams of bytes- either going from your application to a file, the screen or a printer - that's output, or from the keyboard - that's input.

Output with Cout

If you know C, you may know that << is used to shift bits to the left. Eg 3 << 3 is 24. Eg left shift doubles the value so 3 left shifts multiplies it by 8.

In C++, << has been overloaded in the ostream class so that int, float, and strings types (and their variants- eg doubles) are all supported. This is how you do text output, by stringing together multiple items between <<.


cout << "Some Text" << intvalue << floatdouble << endl;

This peculiar syntax is possible because each of the << is actually a function call which returns a reference to an ostream object. So a line like the above is actually like this


cout.<<("some text").cout.<<( intvalue ).cout.<<(floatdouble).cout.<<(endl) ;

The C function printf was able to format output using Format Specifiers such as %d. In C++ cout can also format output but uses a different way of doing it.

02
of 08

Using Cout to Format Output

The object cout is a member of the iostream library. Remember that this has to be included with a


#include <iostream>

This library iostream is derived from ostream (for output) and istream for input.

Formatting of text output is done by inserting manipulators into the output stream.

What Is a Manipulator?

It's a function that can alter the characteristics of the output (and input) stream. On the previous page we saw that << was an overloaded function that returned a reference to the calling object e.g. cout for output or cin for input. All manipulators do this so you can include them in the output << or input >>. We'll look at input and >> later on in this lesson.


count << endl;

endl is a manipulator which ends the line (and starts a new one). It is a function that can also be called in this way.


endl(cout) ;

Though in practice you wouldn't do that. You use it like this.


cout << "Some Text" << endl << endl; // Two blank lines

Files Are Just Streams

Something to bear in mind that with much development these days being done in GUI applications, why would you need text I/O functions? Isn't that just for console applications? Well you will probably do file I/O and you can use them there as well but also what is output to screen usually needs formatting as well. Streams are a very flexible way of handling input and output and can work with

  • Text I/O. As in console applications.
  • Strings. Handy for formatting.
  • File I/O.

Manipulators Again

Although we have been using the ostream class, it is a derived class from the ios class which derives from the ios_base. This ancestor class defines the public functions which are manipulators.

03
of 08

List of Cout Manipulators

Manipulators can be defined in input or output streams. These are objects that return a reference to the object and are placed between pairs of <<. Most of the manipulators are declared in <ios>, but endl, ends and flush come from <ostream>. Several manipulators take one parameter and these come from <iomanip>.

Here's a more detailed list.

From <ostream>

  • endl - Ends the line and calls flush.
  • ends - Inserts '\0' ( NULL) into the stream.
  • flush - Force the buffer to be output immediately.

From <ios>. Most are declared in <ios_base> the ancestor of <ios>. I've grouped them by function rather than alphabetically.

  • boolalpha - Insert or extract bool objects as "true" or "false".
  • noboolalpha - Insert or extract bool objects as numeric values.
  • fixed - Insert floating-point values in fixed format.
  • scientific - Insert floating-point values in scientific format.
  • internal - Internal-justify.
  • left - Left-justify.
  • right - Right-justify.
  • dec - Insert or extract integer values in decimal format.
  • hex - Insert or extract integer values in hexadecimal (base 16) format.
  • oct - Insert or extract values in octal (base 8) format.
  • noshowbase - Do not prefix value with its base.
  • showbase - Prefix value with its base.
  • noshowpoint - Do not show decimal point if not necessary.
  • showpoint - Always show decimal point when inserting floating-point values.
  • noshowpos - Don't insert plus sign (+) if number >= 0.
  • showpos - Do insert plus sign (+) if number >=0.
  • noskipws - Do not skip initial white space on extracting.
  • skipws - Skip initial white space on extracting.
  • nouppercase - Don't replace lowercase letters by uppercase equivalents.
  • uppercase - Replace lowercase letters by uppercase equivalents.
  • unitbuf - Flush buffer after an insert.
  • nounitbuf - Don't flush buffer after each insert.
04
of 08

Examples Using Cout

 // ex2_2cpp
#include "stdafx.h"
#include <iostream>
using namespace std;
int main(int argc, char* argv[])
{
cout.width(10) ;
cout << right << "Test" << endl;
cout << left << "Test 2" << endl;
cout << internal <<"Test 3" << endl;
cout << endl;
cout.precision(2) ;
cout << 45.678 << endl;
cout << uppercase << "David" << endl;
cout.precision(8) ;
cout << scientific << endl;
cout << 450678762345.123 << endl;
cout << fixed << endl;
cout << 450678762345.123 << endl;
cout << showbase << endl;
cout << showpos << endl;
cout << hex << endl;
cout << 1234 << endl;
cout << oct << endl;
cout << 1234 << endl;
cout << dec << endl;
cout << 1234 << endl;
cout << noshowbase << endl;
cout << noshowpos << endl;
cout.unsetf(ios::uppercase) ;
cout << hex << endl;
cout << 1234 << endl;
cout << oct << endl;
cout << 1234 << endl;
cout << dec << endl;
cout << 1234 << endl;
return 0;
}

The output from this is below, with one or two extra line spaces removed for clarity.

 Test
Test 2
Test 3
46
David
4.50678762E+011
450678762345.12299000
0X4D2
02322
+1234
4d2
2322
1234

Note: Despite the uppercase, David is printed as David and not DAVID. This is because uppercase only affects generated output- e.g. numbers printed in hexadecimal. So the hex output 4d2 is 4D2 when uppercase is in operation.

Also, most of these manipulators actually set a bit in a flag and it is possible to set this directly with

 cout.setf() 

and clear it with

 cout.unsetf() 
05
of 08

Using Setf and Unsetf to Manipulate I/O Formatting

The function setf has two overloaded versions shown below. While unsetf just clears the specified bits.

 setf( flagvalues) ;
setf( flagvalues, maskvalues) ;
unsetf( flagvalues) ;

The variable flags is derived by ORing together all the bits you want with |. So if you want scientific, uppercase and boolalpha then use this. Only the bits passed in as the parameter are set. The other bits are left unchanged.

 cout.setf( ios_base::scientific | ios_base::uppercase | ios_base::boolalpha) ;
cout << hex << endl;
cout << 1234 << endl;
cout << dec << endl;
cout << 123400003744.98765 << endl;
bool value=true;
cout << value << endl;
cout.unsetf( ios_base::boolalpha) ;
cout << value << endl;

Produces

 4D2
1.234000E+011
true
1

Masking Bits

The two parameter version of setf uses a mask. If the bit is set in both the first and second parameters then it gets set. If the bit is only in the second parameter then it is cleared. The values adjustfield, basefield and floatfield (listed below) are composite flags, that is several flags Or'd together. For basefield with the values 0x0e00 is the same as dec | oct | hex. So

 setf( ios_base::hex,ios_basefield ) ; 

clears all three flags then sets hex. Similarly adjustfield is left | right | internal and floatfield is scientific | fixed.

List of Bits

This list of enums is taken from Microsoft Visual C++ 6.0. The actual values used are arbitrary- another compiler may use different values.

 skipws = 0x0001
unitbuf = 0x0002
uppercase = 0x0004
showbase = 0x0008
showpoint = 0x0010
showpos = 0x0020
left = 0x0040
right = 0x0080
internal = 0x0100
dec = 0x0200
oct = 0x0400
hex = 0x0800
scientific = 0x1000
fixed = 0x2000
boolalpha = 0x4000
adjustfield = 0x01c0
basefield = 0x0e00,
floatfield = 0x3000
_Fmtmask = 0x7fff,
_Fmtzero = 0

06
of 08

About Clog and Cerr

Like cout, clog and cerr are pre-defined objects defined in ostream. The iostream class inherits from both ostream and istream so that's why the cout examples can use iostream.

Buffered and Unbuffered

  • Buffered - All output is temporarily stored in a buffer and then dumped to screen in one go. Both cout and clog are buffered.
  • Unbuffered- All output goes immediately to the output device. An example of an unbuffered object is cerr.

The example below demonstrates that cerr is used in the same way as cout.


#include <iostream>
using namespace std;
int _tmain(int argc, _TCHAR* argv[])
{ cerr.width(15) ;
cerr.right;
cerr << "Error" << endl;
return 0;
}

The main problem with buffering, is if the program crashes then the buffer contents are lost and it's harder to see why it crashed. Unbuffered output is immediate so sprinkling a few lines like this through the code might come in useful.

 cerr << "Entering Dangerous function zappit" << endl; 

The Logging Problem

Building a log of program events can be a useful way to spot difficult bugs- the type that only occur now and then. If that event is a crash though, you have the problem- do you flush the log to disk after every call so you can see events right up to the crash or keep it in a buffer and periodically flush the buffer and hope you don't lose too much when the crash occurs?

07
of 08

Using Cin for Input: Formatted Input

There are two types of input.

  • Formatted. Reading input as numbers or of a certain type.
  • Unformatted. Reading bytes or strings. This gives much greater control over the input stream.

Here is a simple example of formatted input.

 // excin_1.cpp : Defines the entry point for the console application.
#include "stdafx.h" // Microsoft only
#include <iostream>
using namespace std;
int main(int argc, char* argv[])
{
int a = 0;
float b = 0.0;
int c = 0;
cout << "Please Enter an int, a float and int separated by spaces" <<endl;
cin >> a >> b >> c;
cout << "You entered " << a << " " << b << " " << c << endl;
return 0;
}

This uses cin to read three numbers (int, float,int) separated by spaces. You must press enter after typing the number.

3 7.2 3 will output "You entered 3 7.2 3".

Formatted Input has Limitations!

If you enter 3.76 5 8, you get "You entered 3 0.76 5", all other values on that line are lost. That is behaving correctly, as the . is not part of the int and so marks the start of the float.

Error Trapping

The cin object sets a fail bit if the input was not successfully converted. This bit is part of ios and can be read by use of the fail() function on both cin and cout like this.

 if (cin.fail() ) // do something

Not surprisingly, cout.fail() is rarely set, at least on screen output. In a later lesson on file I/O, we'll see how cout.fail() can become true. There is also a good() function for cin, cout etc.

08
of 08

Error Trapping in Formatted Input

Here is an example of input looping until a floating point number has been correctly entered.

 // excin_2.cpp
#include "stdafx.h" // Microsoft only
#include <iostream>
using namespace std;
int main(int argc, char* argv[])
{
float floatnum;
cout << "Enter a floating point number:" <<endl;
while(!(cin >> floatnum))
{
cin.clear() ;
cin.ignore(256,'\n') ;
cout << "Bad Input - Try again" << endl;
}
cout << "You entered " << floatnum << endl;
return 0;
}

clear() ignore

Note: An input such as 654.56Y will read all the way up to the Y, extract 654.56 and exit the loop. It is considered valid input by cin

Unformatted Input

I/O

Keyboard Entry

cin Enter Return

This ends the lesson.

Format
mla apa chicago
Your Citation
Bolton, David. "Learn About Input and Output in C++." ThoughtCo, Feb. 16, 2021, thoughtco.com/learn-about-input-and-output-958405. Bolton, David. (2021, February 16). Learn About Input and Output in C++. Retrieved from https://www.thoughtco.com/learn-about-input-and-output-958405 Bolton, David. "Learn About Input and Output in C++." ThoughtCo. https://www.thoughtco.com/learn-about-input-and-output-958405 (accessed March 28, 2024).