User Tools

Site Tools


en:cs:cpp:common:basicio

Girdi ve Çıktı Akışları

Input and output functionality is not defined as part of the C++ language, but is instead provided through the C++ standard library.

Many C++ books do not cover this functionality because it is not part of the base language. However, just because this functionality is not part of C++ does not mean that C++ does not support it. For C++ to support this functionality, the <iostream> header file, which is part of the C++ standard library, is used.

What is Flow?

In its simplest form, input and output in C++ are implemented with streams. A stream is an array of bytes that can be accessed sequentially. Over time, a stream can potentially produce or consume an unlimited amount of data.

We usually deal with 2 types of flows.

Input streams are used to hold input from a data producer such as a keyboard, file or network. For example, the user can press a key when the program is not expecting any input. Instead of completely ignoring this action of the user, C++ keeps this input in a stream, the data is put into an input stream and waits there until the program is ready.

Output streams are used to hold the output of a specific data consumer such as a monitor, file or printer. When writing data to an output device, the device may not yet be ready to accept the data. For example, the printer may still be warming up when the program writes data to the output stream. The data will remain in the output stream until it starts to be consumed by the printer.

Of course, some instruments can be sources of inputs and outputs. For example files and networks.

The programmer only needs to learn how to control these streams. It does not need to know how the streams interact with devices and resources such as files and networks in the background. This part depends on the environment and the operating system.

The istream class is the primary class used when dealing with input streams. In input streams, the subtraction operator (») is used to remove values from the stream.

The ostream class is the primary class used when dealing with output streams. In output streams, the append operator («) is used to place values into the stream.

The iostream class can handle both input and output and allows bidirectional input/output. Both istream and ostream are derived from the class named ios

Standard Flows

A standard flow is a pre-connected flow provided to a computer program by its environment. C++ comes with four predefined standard flow objects for your use.

  • cin – an istream object bound to standard input (typically keyboard)
  • cout – an ostream object connected to standard output (typically a monitor)
  • cerr – an ostream object that provides unbuffered output, connected to standard error (typically the monitor)
  • clog – an ostream object that provides buffered output, connected to standard error (typically the monitor)

Unbuffered output is usually processed immediately, while buffered output is usually stored and written as a block. Since Clog is not used very often, it is usually excluded from the list of standard streams.

Input with istream

The iostream library provides a wide and varied input functionality. Only the necessary information for the input is included here. There are many sub-stream functions. See basic_istream for details.

Subtraction operator

We can use the subtraction operator (») to read information from an input stream.

C++ has a default subtraction operator for all basic data types. We have also seen how we can overload this operator for our own class types.

Caution when using the extraction operator. In case the input exceeds our buffer object.

char buf[10];
std::cin >> buf;

For example, in the code above, what happens if the user enters more than 10 characters? A situation called buffer overflow occurs and can cause undefined behavior.

We can use manipulators to prevent such situations.

Manipulator is an object used to modify a stream when applied with the subtract (») or add («) operators.

#include <iomanip>
char buf[10];
std::cin >> std::setw(10) >> buf;

In the above example, with the setw() manipulator, we have ensured that the subtraction operator receives a maximum of 9 characters 1) The remaining inputs will remain in the stream until the next subtraction operation.

Another thing to know is that the subtraction operator ignores gaps. To avoid this, we can use the get() function, which is also in the istream class.

    char ch;
    while (std::cin.get(ch))
        std::cout << ch;

Likewise, there is an alternative to the get() function for strings. The following example retrieves a string 10 characters long from the user. The rest remains in the stream in the same way.

    char strBuf[11];
    std::cin.get(strBuf, 11);
    std::cout << strBuf << '\n';

There is an important point to know about these two get() examples. This function does not read the character \n''. When it encounters this character, it considers the read operation finished. We can use the ''getline()'' function for this case. The function ''getline()'' works in the same way, except that it also reads the character ''\n%%%.

    char strBuf[11];
    // 10 karaktere kadar okuma
    std::cin.getline(strBuf, 11);
    std::cout << strBuf << '\n';
 
    // 10 karaktere kadar daha okuyun
    std::cin.getline(strBuf, 11);
    std::cout << strBuf << '\n';

out with ostream and ios

Insertion Operator

The insertion operator («) is used to put information into an output stream. C++ has predefined append operations for all built-in data types

Formatting

There are two ways to change formatting: flags and manipulators. You can think of flags as boolean variables that can be turned on and off. Manipulators are objects placed in a stream that affect the way objects enter and exit.

We can use the setf() and unsetf() functions to change the flags. For example, in c++, as in math, we do not write the + sign in front of positive numbers by default. We can enable printing with the std::ios::showpos flag.

std::cout.setf(std::ios::showpos); // std::ios::showpos bayrağını açtık.
std::cout << 27 << '\n';

To activate more than one flag, we can use the | oparet.

std::cout.setf(std::ios::showpos | std::ios::showpoint); // std::ios::showpos ve std::ios::showpoint bayrağını açtık.
std::cout << 27 << '\n';

In the same way, we can use the unsetf() function to turn off a flag.

std::cout.setf(std::ios::showpos); // std::ios::showpos bayrağını açın
std::cout << 27 << '\n';
std::cout.unsetf(std::ios::showpos); // std::ios::showpos bayrağını kapatın
std::cout << 28 << '\n';

Another thing to know about flags is that some flags belong to certain groups. These groups are called format groups and format groups keep flags with similar functionality together. The functions setf() and unsetf() are not as smart as expected in handling these groups of flags.

For example, the format group basefield has the flags oct, dec and hex which determine the base in which the integer output is processed. By default the dec flag is on.

If we want to print in hexadecimal by turning on the hex flag. Separately we need to turn off the dec flag. Because the setf() function is smart enough not to turn off the dec flag when we set the hex flag. As a result, our code will not work as expected because the dec flag has priority over the hex flag.

std::cout.setf(std::ios::hex); // We tried to open the hex output.
std::cout << 27 << '\n';

Kodu bize;

27

It will give the result. Because the dec flag is on, it will process the number 27 as decimal. What we really need to do is;

std::cout.unsetf(std::ios::dec); // dec çıkışını kapattık.
std::cout.setf(std::ios::hex); // hex çıkışını açmayı denedik.
std::cout << 27 << '\n';

Another convenience is the second parameter of the setf() function. By typing the name of the group in the second parameter, we can turn off other flags in that group except the flag we turned on.

std::cout.setf(std::ios::hex, std::ios::basefield);
std::cout << 27 << '\n';

This way of formatting the output is not very common. C++ gives us a second formatting method. This method is manipulators. The good thing about manipulators is that they can remember to turn off other flags according to the flag we set.

std::cout << std::hex << 27 << '\n'; // Print 27 in hexadecimal
std::cout << 28 << '\n'; // Hala hex'teyiz.
std::cout << std::dec << 29 << '\n'; // back to the decimal system

Yukarıdaki kod bize ;

1b
1c
29

Sonucunu verecektir.

So why use manipulators and learn to turn flags on and off? Many options can usually be set with manipulators or flags. But some settings can only be set with the manipulator or only with the flag. So it is necessary to know both.

Other Formatters

Flags, manipulators and member functions that you may commonly encounter are listed below.

  • Flags are of class std::ios.
  • Manipulators reside in the std:: namespace.
  • Member functions are contained in the std::ostream class.
  • If the std::ios::boolalpha flag is on, bool values are printed as true or false. If it is off, bool values are printed as 1 or 0. It is off by default.
  • The manipulator std::boolalpha prints bool values “true” or “false”
  • std::noboolalpha manipulator prints bool values 0 or 1 (default)
std::cout << true << ' ' << false << '\n';
std::cout.setf(std::ios::boolalpha);
std::cout << true << ' ' << false << '\n';
std::cout << std::noboolalpha << true << ' ' << false << '\n';
std::cout << std::boolalpha << true << ' ' << false << '\n';
  • If the std::ios::showpos flag is on, it puts + in front of positive numbers. If it is off, it does not. It is off by default.
  • The manipulator std::showpos puts + in front of positive numbers.
  • The manipulator std::noshowpos does not put + in front of positive numbers (default)
std::cout << 5 << '\n';
std::cout.setf(std::ios::showpos);
std::cout << 5 << '\n';
std::cout << std::noshowpos << 5 << '\n';
std::cout << std::showpos << 5 << '\n';
  • Capital letters are used if the std::ios::uppercase flag is on. It is off by default.
  • Capital letters are used with the std::uppercase manipulator.
  • Lowercase letters are used with the manipulator std::nouppercase (default)
std::cout << 123456.8 << '\n';
std::cout.setf(std::ios::uppercase);
std::cout << 123456.8 << '\n';
std::cout << std::nouppercase << 123456.8 << '\n';
std::cout << std::uppercase << 123456.8 << '\n';
  • std::ios::basefield format group;
    • If the std::ios::dec flag is set, print values in decimal (default)
    • If the std::ios::hex flag is set, it prints values in hexadecimal.
    • If the std::ios::oct flag is set, it prints values in octal.
  • The std::dec manipulator prints values in decimal (default)
  • The manipulator std::hex prints values in hexadecimal.
  • The manipulator std::oct prints values in octal.
std::cout << 27 << '\n';
std::cout.setf(std::ios::dec, std::ios::basefield);
std::cout << 27 << '\n';
std::cout.setf(std::ios::oct, std::ios::basefield);
std::cout << 27 << '\n';
std::cout.setf(std::ios::hex, std::ios::basefield);
std::cout << 27 << '\n';
std::cout << std::dec << 27 << '\n';
std::cout << std::oct << 27 << '\n';
std::cout << std::hex << 27 << '\n';
  • std::ios::floatfield format group;
    • If the std::ios::fixed flag is set, use decimal notation for fractional numbers (default)
    • If the std::ios::scientific flag is on, it uses scientific notation for fractional numbers.
    • If the std::ios::showpoint flag is on, it always shows a decimal point and trailing 0s for fractional values.
    • If the flag is not specified, constant is used for low-digit numbers, otherwise scientific is used.
  • The std::fixed manipulator uses the decimal system (default)
  • The manipulator std::scientific uses scientific notation.
  • The manipulator std::showpoint shows the decimal point and trailing 0s for fractional values.
  • The manipulator std::noshowpoint does not display the decimal point and trailing 0s for fractional values.
  • The manipulator std::setprecision(int) sets the precision of fractional numbers (found in the iomanip header).
  • The member function std::ios_base::precision() returns the current precision of fractional numbers.
  • The member function std::ios_base::precision(int) sets the precision of fractional numbers and returns the old precision.

If using constant or scientific notation, the precision determines how many decimal places are displayed in the fraction. Note that if the precision is less than the number of significant digits, the number will be rounded.

std::cout << std::fixed << '\n';
std::cout << std::setprecision(3) << 123.456 << '\n';
std::cout << std::setprecision(4) << 123.456 << '\n';
std::cout << std::setprecision(5) << 123.456 << '\n';
std::cout << std::setprecision(6) << 123.456 << '\n';
std::cout << std::setprecision(7) << 123.456 << '\n';
std::cout << std::scientific << '\n';
std::cout << std::setprecision(3) << 123.456 << '\n';
std::cout << std::setprecision(4) << 123.456 << '\n';
std::cout << std::setprecision(5) << 123.456 << '\n';
std::cout << std::setprecision(6) << 123.456 << '\n';
std::cout << std::setprecision(7) << 123.456 << '\n';

Kodu bize;

123.456
123.4560
123.45600
123.456000
123.4560000

1.235e+002
1.2346e+002
1.23456e+002
1.234560e+002
1.2345600e+002

If neither a fixed nor a scientific method is used, precision determines how many significant digits are displayed. Again, if the precision is less than the number of significant digits, the number will be rounded.

std::cout << std::setprecision(3) << 123.456 << '\n';
std::cout << std::setprecision(4) << 123.456 << '\n';
std::cout << std::setprecision(5) << 123.456 << '\n';
std::cout << std::setprecision(6) << 123.456 << '\n';
std::cout << std::setprecision(7) << 123.456 << '\n';

Code gives us.

123
123.5
123.46
123.456
123.456

You can use the showpoint manipulator or flag to make the stream write a decimal point and trailing zeros.

std::cout << std::showpoint << '\n';
std::cout << std::setprecision(3) << 123.456 << '\n';
std::cout << std::setprecision(4) << 123.456 << '\n';
std::cout << std::setprecision(5) << 123.456 << '\n';
std::cout << std::setprecision(6) << 123.456 << '\n';
std::cout << std::setprecision(7) << 123.456 << '\n';

Code gives us.

123.
123.5
123.46
123.456
123.4560

Taken from UCH Viki. https://wiki.ulascemh.com/doku.php?id=en:cs:cpp:common:basicio Çıkarma operatörü başlığında ikinci satırda aşırı yükleme kısmına link verilecek.

1)
One is reserved for the terminator.
en/cs/cpp/common/basicio.txt · Last modified: 2025/05/02 22:21 by ulascemh