前面学习了循环的工作原理,接下来来看看循环完成的一项最常见的任务:逐字符地读取来自文本或键盘的文本。
15.1、使用cin进行输入
如果需要程序使用循环来读取来自键盘的文本输入,则必须有办法直到何时停止读取。一种方式是选择某个特殊字符作为停止标志,例如下面这个程序:
#include <iostream>
int main()
{
using namespace std;
char ch;
int count = 0;
cout << "Enter characters;enter ! to quit:" << endl;
cin >> ch;
while (ch != '!')
{
cout << ch;
++count;
cin >> ch;
}
cout << endl << count << " characters read" << endl;
return 0;
}
该程序在循环之前读取第一个输入字符,这样测试可以测试第一个字符是否为!,如果第一个为!,则可以跳过循环。
如果读取的第一个字符不是!,则程序进入该循环,显示字符,增加计数,然后读取下一个字符。读取下一个字符这一个操作十分重要,如果没有这一步,循环将会反复处理第一个字符。
但是如果我们输入空格,程序输出时将会跳过空格,这是因为cin在读取char值的时候,会忽略空格和换行符。
15.2、使用cin.get(char)进行补救
cin所属的istream类(在iostream中定义)中包含一个能够满足这种要求的成员函数。具体来说,成员函数cin.get(ch)读取输入中的下一个字符(即使为空格也读取),将其赋给变量ch。
#include <iostream>
int main()
{
using namespace std;
char ch;
int count = 0;
cout << "Enter characters;enter ! to quit:" << endl;
cin.get(ch);
while (ch != '!')
{
cout << ch;
++count;
cin.get(ch);
}
cout << endl << count << " characters read" << endl;
return 0;
}
现在程序了写出每个字符,并将全部字符计算在内,其中包括空格。如果学过C语言,应该知道函数不加取地址符将会传值而不会改变变量,在C语言是无效的,但是在C++只要将参数声明为引用即可。引用是C++在C语言的基础上新增的一种类型,头文件iostream将cin.get(ch)的参数声明为引用类型,因此函数可以修改其参数的值。
15.3、使用哪一个cin.get()
在第七篇写过一段代码:
char name[ArSize];
……
cout << "Enter your name:" << endl;
cin.get(name, ArSize).get();
最后一行相当于连用两次函数调用:
cin.get(name, ArSize);
cin.get();
cin.get()的一个版本接受两个参数:数组名(字符串(char*类型)的地址)和ArSize(int类型的整数)。(数组名是该数组第一个元素的地址)
而这里我们这样使用cin.get():
char ch;
cin.get(ch);
这里cin.get()接受一个char参数。与前面不同,为何可以传递一个参数?在C++中,因为它支持被称为函数重载的OOP特性,允许创建多个同名函数,条件是它们的参数列表不同。
15.4、文件尾条件
其实前面以!等符号为输入结束标志不太好用,这些符号本就合法且常用。如果输入来自于文件,则可以使用一种功能更强大的技术——检测文件尾(EOF)。
读取文本中的信息似乎同cin和键盘输入没什么关系,但其实存在两个相关的地方。首先,很多操作系统都支持重定向,允许文件替换键盘输入;其次很多操作系统都允许通过键盘来模拟文件尾条件,很多PC编程环境都将Ctrl+Z视为默认的EOF,但具体细节各不相同。如果编译环境能够检测EOF,可以在类似上面的程序中使用重定义的文件。
#include <iostream>
int main()
{
using namespace std;
char ch;
int count = 0;
cin.get(ch);
while (cin.fail() == false)
{
cout << ch;
++count;
cin.get(ch);
}
cout << endl << count << " characters read" << endl;
return 0;
}
注:vs2022有和这篇文章相似的问题 ,摁了一下enter键就解决了问题。(^Z是ctrl+z出来的)
15.5、另一个cin.get()版本
不接受任何参数的cin。get()成员函数返回输入中的下一个字符。也就是说,可以这样使用它:
ch=cin.get();
该函数的工作方式与C语言中的getchar()相似,将字符编码作为int值返回;而cin.get(ch)返回一个对象,而不是读取的字符。
为成功地使用cin.get(),需要知道其知道处理EOF条件。当该函数到达EOF时,将没有可返回的字符。cin.get()将会返回一个符号常量EOF表示的特殊值。该常量是在头文件iostream中定义的。
前面我们是这么写的:
char ch;
int count = 0;
cin.get(ch);
while (cin.fail() == false)
{
cout << ch;
++count;
cin.get(ch);
}
而我们可以用int ch,并用cin.get()代替cin.get(char),用cout.put()(在第三篇有写)代替cout,用EOF测试代替cin.fail()测试:
int ch;
int count = 0;
ch=cin.get();
while (ch!=EOF)
{
cout.put(ch);
++count;
ch=cin.get();
}
下面是cin.get(char)和cin.get()之间的区别: