Header files to include when using C++ I/O.
#include<iostream>
Include this file whenever using C++ I/O.
#include<iomanip>
This file must be included for most C++ manipulators.
#include<fstream>
Include this file whenever working with files.
By default, leading whitespace (carriage returns, tabs, spaces) is ignored by cin.
Given:
int i; float fl; std::cin >> fl; std::cin >> i;
And you type: 3.14<return>42<return>
std::cin.getline() can run into problems when used with std::cin » var.
getline can be provided a third argument; a “stop” character. This character ends getline's input. The character is eaten and the string is terminated.
Example:
std::cin.getline(str, 100, '|')
If std::cin.getline() is not provided a “stop” character as a third argument, it will stop when it reaches a newline.
Given:
float fl; std::cin >> fl; char str[101] std::cin.getline(str, 101);
And you type: 3.14<return>
The solution is to add std::cin.ignore(); immediately after the first std::cin statement. This will grab a character off of the input buffer (in this case, newline) and discard it.
std::cin.ignore() can be called three different ways:
std::cin.ignore(); //discard 1 character
std::cin.ignore(33); //discard 33 characters
std::cin.ignore(26, '\n'); //ignore 26 characters or to a newline, whichever comes first
If std::cin is presented with input it cannot process, std::cin goes into a “fail” state.
The input it cannot process is left on the input stream.
All input will be ignored by std::cin until the “fail” state is cleared: std::cin.clear().
A routine that reads a number directly should:
Inputting numbers directly, version 1:
#include<limits> //for numeric_limits float fl; int bad_input; do{ bad_input=0; std::cin >> fl; if(!std::cin) { bad_input=1; std::cin.clear(); std::cin.ignore(std::numeric_limits<streamsize>::max(),'\n'); } }while(bad_input);
Inputting numbers directly, version 2:
#include<limits> //for numeric_limits float fl; while(!(std::cin >> fl)) { std::cin.clear(); std::cin.ignore(std::numeric_limits<streamsize>::max(),'\n'); }
NOTE: A note on limits. If your compiler doesn't support std::numeric_limits<streamsize>::max(), an alternative is to use the c-style method for determining the maximum integer allowed:
#include<climits> ... std::cin.ignore(INT_MAX, '\n');
#include <cstdlib> ... int i; float fl; char temp[100]; std::cin.getline(temp, 100); fl=strtof(temp,0); std::cin.getline(temp, 100); i=strtol(temp,0,10);
std::ifstream someVarName("data.txt"); float fl; char temp[100]; someVarName.getline(temp, 100); fl=strtof(temp); int i; someVarName >> i;
std::ifstream inf("data.txt"); char temp[100]; while(!inf.getline(temp, 100).eof()) { //process the line }
If the expression in the while() loop above is confusing, I've provided an explanation: UnderstandingComplexExpressions.pdf.
char temp[100]; std::cin.getline(temp, 100, '|');
Given data file:
John|83|52.2 swimming|Jefferson Jane|26|10.09 sprinting|San Marin
Process using:
std::ifstream inf("data.txt"); char name[30]; while(!inf.getline(name, 30, '|').eof()) { Athlete* ap; char jersey_number[10]; char best_time[10]; char sport[40]; char high_school[40]; inf.getline(jersey_number, 10, '|'); #read thru pipe inf.getline(best_time, 10); #read thru newline inf.getline(sport, 40, '|'); #read thru pipe inf.getline(high_school, 40); #read thru newline ap = new Athlete(name, strtod(number), strtof(best_time), sport, high_school); //do something with ap }
All of the previous examples have assumed that C-style strings (null-terminated character arrays) were being used. C++ provides a string class that, when combined with a particular “getline” function, can dynamically resize to accommodate user input. In general, C++ strings are preferred over C strings.
Given data file:
John|83|52.2 swimming|Jefferson Jane|26|10.09 sprinting|San Marin
Here is the same code shown above, this time using C++ strings:
#include <string> std::ifstream inf("data.txt"); string name; while(!std::getline(inf, name, '|').eof()) { Athlete* ap; std::string jersey_number; std::string best_time; std::string sport; string high_school; std::getline(inf, jersey_number, '|'); #read thru pipe std::getline(inf, best_time); #read thru newline std::getline(inf, sport, '|'); #read thru pipe std::getline(inf, high_school); #read thru newline ap = new Athlete(name, strtod(number.c_str()), strtof(best_time.c_str()), sport, high_school); //do something with ap }
How to prepare the output stream to print fixed precision numbers (3.40 instead of 3.4)
std::cout.setf(std::ios::fixed, std::ios::floatfield); std::cout.setf(std::ios::showpoint); std::cout.precision(2);
Given: int one=4, two=44;
std::cout << one << std::endl.; //output: "4" std::cout << setw(2) << one << std::endl.; //output: " 4" std::cout.fill('X'); std::cout << setw(2) << one << std::endl.; //output: "X4" std::cout.fill('X'); std::cout << setw(2) << two << std::endl.; //output: "44"