c++中一些处理i/o流和文件流信息的方法总结

来源:互联网 发布:网络拓扑图的网络设备 编辑:程序博客网 时间:2024/06/04 22:38

处理i/o流(cin, cout)

1.处理缓冲区

关于缓冲区的概念,看一个例子:
#include <iostream>
using namespace std;
int main() {
int a;
cin >> a;
cout << a << endl;
cout << "press Enter to end" << endl;
cin.get();
}

如果直接输入23并按回车,那么程序会直接结束而不会等你press Enter,为什么呢?
cin对象从控制台(键盘)读取输入,每当用户按一次回车(注意:cin使用空格,\t,\n来作为输入字符串的结束标志,但只有回车符会刷新缓冲区),他所敲入的东西会一次性发送给程序(并非敲一个读一个),程序会将数据放在为它保留的缓冲区中,包括末尾的回车,之后,cin把输入数据赋给指定变量,不断从缓冲区抽取。上述程序将“23回车”放入缓冲区“,然后23赋给a,回车被get()读取,程序结束。
这种安排会产生许多问题,比如在多项输入时,用户在输入第一项(y或n)时,输入了”yedd“,那么”edd“会赋值给第二个问题。
解决:
及时清除多余的缓冲区数据,在cin >> a后面加一句:
cin.ignore(100);//删除缓冲区100个字
或者:
cin.ignore(100, ‘\n’);//删除缓冲区100个字符或直到遇到换行符

2.读入时检查类型是否匹配

当程序要求输入一个数值而用户输入非数值时,程序可能会做出不同反应,比如可能转换为某种数值形式,也可能死机,因而我们最好通过检查用户输入来降低这种风险。
cin有几个专门报告工作状态的成员函数:
eof() :如果到达输入(文件)的末尾,返回true;
fail() :如果cin无法工作,返回true;
bad():如果cin因为比较严重的原因(比如内存不足)而无法工作,返回true;
good():如果以上情况均没有发生(即有效且未到达结尾),返回true。
如果输入时出错,应进行下列处理:先调用clear()函数清除出错状态,再调用ignore()函数清除缓冲区(clear()只清除出错状态不清理缓冲区)
cin.clear();
cin.ignore(100, '\n');
检查是否正确输入数值:
int a;
while(!(cin >> a)) //用于判断是否有有效的输入流(此处!(cin >> a).good()也可)
{
cin.clear();
cin.ignore(100, '\n');
cout << "Enter correctly please:" << endl;
}

而检查string输入规范呢?毕竟数字也可以是字符串,因此我们对输入赋值后的string进行检查单个字符我们可以用cctype库里函数来检查:
isalnum():是否为字母或数字;
isalpha():是否为字母;
isdigit():是否为数字;
里面还定义了toupper()和tolower()函数来改变字母的大小写 (返回大小写)。
以上均为单字符操作

3.数值输出规范

1.限制被输出数值的最大位数(此法在整数部分长度大于所设置的长度时不起作用):
cout.precision(4);
cout << "2.3449"; // 2.345,注意此法进行了四舍五入
cout.precision(3);
cout << "322.3449"; // 322
关于precision()这个函数:
precision() 返回当前的浮点数精度值
precision(val) 设置val为新的浮点数精度值, 并返回原值

2.将浮点数小数点后位数进行限制(此法在整数部分长度大于所设置的长度时不起作用):
cout.setf(ios::fixed); // 使用定点记号(与默认的浮点记号相对立)
cout.setf(showpoint); // 输出时不得省略小数点
cout.precision(3); // 设置小数点后精确度
cout << 2.3449; // 2.345,注意有四舍五入
cout << 30; // 30.000

3.固定输出宽度(空白处在左补齐)(此法在长度大于所设置的长度时不起作用):
#include < iomanip>
//...
int a = 42;
cout << setw(5) << setfill('0') << a; // 输出00042

只对随后的一个变量有效(再加 << b不会对b起作用)
默认为右对齐,需要左对齐在cout前加cout.setf(ios::left);.

4.杂项(加+号等):
用setf(ios::@@) @@处内填不同标志有不同作用(ios等同于ios_base):
showpos 正数前面加上+号
uppercase 在以科学计数法输出E和十六进制输出字母X时,使用大写字符
showbase 显示数字的进制
boolalpha bool值使用字符表示 , true或者false
noboolalpha bool使用0和1表示
internal 字符靠左对齐, 数字卡右对齐
left 输出数据在本域宽范围内左对齐
right 输出数据在本域宽范围内右对齐
internal 数值的符号位在域宽内左对齐,数值右对齐,中间由填充字符填充
dec 设置整数的基数为10
oct 设置整数的基数为8
hex 设置整数的基数为16
showbase 强制输出整数的基数(八进制以0打头,十六进制以0x打头)
showpoint 强制输出浮点数的小点和尾数0
scientific 设置浮点数以科学计数法(即指数形式)显示
fixed 设置浮点数以固定的小数位数显示
unitbuf 每次输出后刷新所有流
stdio 每次输出后清除stdout,stderr
标志也可以一起使用 :cout.setf(ios::showpoint | ios::boolalpha) ;
想要去除某个标志使用函数 unsetf(ios:: )。

原创粉丝点击