Witheart... Follow your heart...
目录
Witheart... Follow your heart...
前言
本系列文章作为笔者学习C++的一个记录,希望可以坚持下去。目前使用C++Primer Plus这本书。
本系列文章适合有C语言基础的读者阅读。
学习内容
数字输入处理
利用 cin
int n;
cin >> n;
如果用户错误地输入了单词,而不是数字,将发生以下四件事情:
- n 的值保持不变;
- 不匹配的输入将被保留在输入队列中;
- cin 对象中的一个错误标记被设置;
- 对 cin 方法的调用将返回 false(如果被转换为 bool 类型)。
所以可以使用非数字输入来结束读取数字的循环。并在循环结束后使用 cin.clear() 来重置错误输入标记。此种代码直接将 cin >> n 置于循环测试条件处即可,当错误输入非数字时,该表达式将返回 false,结束输入循环。
也可以使用这种方法来检测用户的输入类型是否正确,如下:
while(!(cin >> arr[i])){
cin.clear();//重置标志位,使可重新输入
while(cin.get() != '\n') continue;//清除行尾之前所有错误的输入
cout << "Please enter a number: ";
}
文件输入输出
cin 智能判断输入类型
使用 cin 进行输入时,程序会将输入的内容视为一系列的字节,每个字节都被解释为字符编码。也就是说,输入的内容一开始都是字符数据,然后 cin 再将字符数据转换为其他类型。
输入下面的文本时
38.5 19.2
会有:
char ch;
cin >> ch;
在上面的代码中,第一个字符是 3,此时输入的是字符,要被赋值的目标变量 ch 也是字符,因此将不会进行任何转换,字符 ’3‘ 的编码将被存储在变量 ch 中,下一个输入操作将处理字符 ’8‘。
int n;
cin >> n;
在上面的代码中,cin 将不断读取,直到遇到非数字吧字符。也就是说,它将读取 38,并将二进制的 38 赋值给 n,而不是字符编码。
double x;
cin >> x;
在上面的代码中,cin 将不断读取,直到遇到第一个不属于浮点数的字符。也就是说,它读取 38.5,然后将浮点格式的数值 38.5 赋给 x。此时空格是输入队列中的下一个字符。
char word[50];
cin >> word;
在上面的代码中,cin 不断读取,直到遇到空白字符。也就是说,它读取 ’3‘、’8‘、’.‘、’5‘ 四个字符,此时空格是输入队列里的下一个字符,然后这四个字符的字符编码将被存储到数组 word 中,并在末尾加上空字符。
注意,空字符的 ASCII 码是 0,而空格的 ASCII 码为 32。
char word[50];
cin.getline(word, 50);
在上面的代码中,cin 不断读取,直到遇到换行符(输入数小于 50)。所有换行符前的内容都被视为字符存储在数组中,包括空格,并且会在结尾加上一个空字符。然后输入队列中的换行符会被丢弃。
写入文本文件
需要包含头文件 fstream,该头文件中包含了一个用于输出的 ofstream 类;
输出内容到文本文件中时,必须声明自己的 ofstream 变量(对象),然后将其和文件关联起来,一种方法是使用open() 方法,文件使用完成后,也需要使用 close() 将其关闭。
ofstream fout;//声明 ofstream 对象
fout.open("fish.txt");//将该对象与 txt 文件 fish.txt 关联起来
//也可以使用下面的代码让用户输入自己想要写入的文本文件
char filename[50];
cin >> filename;
fout.open(filename);
//关联成功后,像使用 cout 一样使用你自己声明的对象就可以(这里是 fout)
当要关联的文本文件不存在时,将被自动创建。当文本文件存在时,对文本文件的操作会覆盖它原有的内容。
读取文本文件
同样的,要先声明属于自己的 ifstream 对象,并且和文件关联起来,操作和写入的时候类似,不再赘述。
注意,当要打开的文件不存在时,将导致使用 ifstream 对象进行输入时失败。可以利用方法 is_open() 检查是否成功打开文件。如下:
fin.open("bowling,txt");
if (!fin.is_open()){
exit(EXIT_FAILURE);
}
成功打开时,返回的是 true,exit() 将终止程序,并且使用同操作系统通信的参数值 EXIT_FAILURE,这需要包含头文件 cstdlib。
注意,Windows 的文本文件每行都以回车符和换行符结尾(这是两个不同的字符),一般来说,C++ 读取文件是将这两个字符转换为换行符,并在写入文件时做相反的转换。
文件读取循环的设计:
fin >> value;//读取文件并将其中的数据赋值给 value
while(fin.good()){
//对变量 value 进行操作
fin >> value;//在用 good 测试读取操作是否成功之前读取
//测试的操作要紧跟着读取操作
}
//以下这些代码放在循环的后面
//用于判断文件读取循环为何停止
if(fin.eof()){
//提示是文件阅读完成导致循环退出
}
else if(fin.fail()){
//提示可能遇到了读取的类型与要赋值的类型不匹配的情况
//到达 EOF 时 fail() 方法也生效,但是该情况在上面 eof() 函数已经判断过
}
else if(fin.bad()){
//可能是文件受损或者硬件故障
}
else{
//提示未知错误
}
同样的,循环读取和测试部分的代码可以简化。表达式 fin >> value 的结果为 fin,在需要 bool 值时,fin 的结果为 fin.good(),是 bool 值。所以可以替换为如下的代码:
while(fin >> value){
//对变量 value 进行操作
}