当使用C ++ I / O时,有三个头文件要包含在内
#include<iostream>
只要使用C ++ I / O,就包括此文件
#include<iomanip>
当使用控制符、操纵符(manipulator
)时,该文件必须包含。
#include<fstream>
每次使用文件时都要包含这个文件。
默认情况下,前导空格(回车符,制表符,空格)被cin忽略。
例如:
int i;
float fl;
std :: cin >> fl;
std :: cin >> i;
然后输入:3.14 <enter> 42 <enter>
- 3.14被读入fl。 3.14之后的换行符(
enter
键)仍然位于输入缓冲区中。 - 由于std :: cin忽略空白,所以第一个换行符被std :: cin >> i“吃掉”。 然后整数42被读入i,第二个换行符留在输入缓冲区中。
std::getline() 在std::cin >> var前使用时可能会出错。
getline
可以提供第三个参数 ——一个“停止”字符。 这个角色确定了getline
的截止输入。 停止字符将从输入流中移除,并且getline
结束。 例如:
//遇到字符'w'时,getline停止,并且'w'移出输入流
std :: getline(std :: cin,str,'w');
- 如果不提供
std :: getline()
作为第三个参数的“停止”字符,它将在到达换行符时停止。
假设:
float fl;
std::cin >> fl;
std::string str;
std::getline(std::cin, str);
- 键盘输入:
3.14 <enter>
3.14
被读入fl
。3.14
之后的换行符仍然位于输入缓冲区中。std :: getline(std::cin,str)
立即处理仍在输入缓冲区中的换行符。 str变成空字符串。- 由此产生了程序跳过执行了
std :: getline()
语句。
解决的办法是在std::cin
之后添加std :: cin.ignore()
。 这将从输入缓冲区中抓取一个字符(在本例中为换行符)并丢弃它。
std :: cin.ignore()
有三种调用方式:
- 无参数:从输入缓冲区中取出一个字符并丢弃:
std :: cin.ignore();
//丢弃一个字符 - 一个参数:从缓冲区中取出并丢弃指定数量的字符:
std :: cin.ignore(33);
//丢弃33个字符 - 两个参数:丢弃的字符数,或丢弃任何字符直到某个字符为止(以先到者为准):
std :: cin.ignore(26,'\n')
; //忽略26个字符或换行符,以先到者为准
直接读取数字是有些许问题的
- 如果
std :: cin
遇到它无法处理的输入,它会进入fail
状态 - 它无法处理的输入保留在输入流中。
- 在调用
std :: cin.clear()
清除fail
状态前,所有输入都将被std :: cin
忽略 - 一个直接读取数字的更强大的例子:
- 读入数字
- 确认输入流仍然正常工作
- 如果输入流无法工作
(!std::cin)
- 调用
std::cin.clear()
使输入流恢复正常状态。 - 从流中删除导致问题的输入:
std::cin.ignore(...)
- 如果可以的话再次获取输入或者处理错误
- 调用
直接读取数字的第一个版本:
#include<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);
第二个版本:
#include<limits>
float fl;
while(!(std::cin >> fl))
{
std::cin.clear();
std::cin.ignore(std::numeric_limits<streamsize>::max(),'\n');
}
使用getline读入数字是直接读取数字的更强大的替代方法
#include <string>
...
int i;
float fl;
std::string temp;
std::getline(std::cin, temp);
fl=std::stof(temp);
std::getline(std::cin, temp);
i=std::stoi(temp);
- getline将读取字符串和数字,而不会进入“失败”状态。
- 使用转换函数,包括:字符串到整数(stoi),字符串到长整数(stol),字符串到浮点(stof),字符串到双精度(stod)
一旦打开一个文件,就可以像使用std :: cin一样使用它。
std::ifstream someVarName("data.txt");
float fl;
std::string temp;
std::getline(someVarName, temp);
fl=std::stof(temp);
int i;
someVarName >> i;
读取整个文件时,将文件输入嵌入到循环条件中
std::ifstream inf("data.txt");
std::string line;
while(!getline(inf, line).eof())
{
//process the line
}
- 一旦达到文件末尾,循环将退出
可以让getline
在遇到任何指定的字符时停止读取
std::string temp;
std::getline(std::cin, temp, '|');
- 如果只有两个参数提供给
getline
,则getline
将在一行的末尾停止(换行符处)。 - 如果向
getline
提供了三个参数,getline
将在第三个参数所指定的字符处停止。 - 停止字符不会被读入到字符串中。
- 停止字符会被消耗掉(从输入流中删除)。
使用while循环和getline可以轻松读取数据被分隔的文件。
假设有如下数据:
John|83|52.2
swimming|Jefferson
Jane|26|10.09
sprinting|San Marin
则可以使用如下方式处理:
std::ifstream inf("data.txt");
std::string name;
while(!std::getline(inf, name, '|').eof())//第一次读取John
{
Athlete* ap;
std::string jersey_number;
std::string best_time;
std::string sport;
std::string high_school;
std::getline(inf, jersey_number, '|'); //第一次读取83
std::getline(inf, best_time); //第一次读取52.2
std::getline(inf, sport, '|'); //第一次读取swimming
std::getline(inf, high_school); //第一次读取Jefferson
ap = new Athlete(name, stoi(number), stof(best_time), sport, high_school);
}
如何让输出流来输出固定的精确数字(例如3.40而不是3.4)
std::cout.setf(std::ios::fixed, std::ios::floatfield);
std::cout.setf(std::ios::showpoint);
std::cout.precision(2);
如何设置打印字段的宽度
假设: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"