cin是用于输入的istream类的一个对象使用cin进行输入时,程序将输入视为一系列的字符,然后cin对象才负责将字符转换为其他类型。在输入数据时,可使用cin >> ch
、cin.get(ch)
、ch = cin.get()
、cin.getline()
等多种方式,看似简单,但其中的细节却非常重要,理解了这些cin
的特点,那么cin
在一些特殊场景下的用法也就一目了然了。如将cin用作测试条件等。
这篇文章中对cin
的使用方式进行下总结。
1.operator >>
最原始的cin >>
输入方式使用如下:
#include <iostream>
int main()
{
using namespace std;
char ch;
int count = 0;
cout << "Enter a character, # to quit:";
cin >> ch;
while (ch != '#')
{
cout << ch;
++count;
cin >> ch;
}
cout << endl<< count << " characters reads" << endl;
system("pause");
return 0;
}
/**
运行并输入:
Enter a character, # to quit:
Today is a nice day #
Todayisaniceday
15 characters reads
/
从运行结果可以看出:
- 1.cin将忽略空白符;
- 2.发送给cin的数据被缓冲,只有在按下Enter后,输入内容才会发送给程序。
2.get(ch& c)
根据示例一,如果要包含输入流中的空白字符,则可以使用成员函数get(ch)
来替代,如下示例:
#include <iostream>
int main()
{
using namespace std;
char ch;
int count = 0;
cout << "Enter characters,# to quit:" << endl;
cin.get(ch);
while (ch != '#')
{
cout << ch;
cin.get(ch);
++count;
}
cout << endl << count << " characters reads." << endl;
system("pause");
return 0;
}
/**
运行:
Enter characters,# to quit:
Today is a nice day.#
Today is a nice day.
20 characters reads.
请按任意键继续. . .
/
可以看到,cin.get(ch)
将会包括空白字符在内的字符输入程序中。
除此之外,cin.get(ch)
的返回值是一个cin对象,而且,istream类提供了一个将istream对象转换为bool值的函数,当cin出现在判断条件中时,如果最后一次读取成功,则返回true,否则返回false。
所以,以上两个示例中的判断条件可以这样修改:
while (cin >> ch && ch != '#')
{
cout << ch;
++count;
}
while (cin.get(ch) && ch != '#')
{
cout << ch;
++count;
}
一般情况下,如果读取单个char字符,使用cin.get(ch)
,如果以行为单位读取数据时。则需要使用以下介绍的这两个方法
3.getline (char* s, streamsize n )
该方法用于读取字符串,它整行进行读取,它通过换行符来确定行尾,但不保存换行符,而是将换行符用空字符来替换。
#include <iostream>
int main()
{
using namespace std;
const int SIZE = 20;
char name[SIZE];
char dessert[SIZE];
cout << "Enter your name:" << endl;
cin.getline(name,SIZE);
cout << "Enter your favorite dessert:" << endl;
cin.getline(dessert,SIZE);
cout << "I have some delicious " << dessert;
cout << " for you, " << name << endl;
return 0;
}
4.get (char* s, streamsize n)
get (char* s, streamsize n)
和getline()
类似,也是以行为单位读取字符串,不同之处在于,它不会丢弃换行符,而是会保留在输入队列中,因此,一般连续调用两次该方法,以清除输入队列中的换行符:
#include <iostream>
int main()
{
using namespace std;
const int SIZE = 20;
char name[SIZE];
char dessert[SIZE];
cout << "Enter your name:" << endl;
cin.get(name,SIZE).get();
cout << "Enter your favorite dessert:" << endl;
cin.get(dessert,SIZE).get();
cout << "I have some delicious " << dessert;
cout << " for you, " << name << endl;
return 0;
}
如果读取空行,get()
读取空行后将设置一个失效位,并阻断接下来的输入;
如果读取字符过长,两者都会将多余的字符留在输入队列中,getline()
还会设置一个失效位,并阻断接下来的输入。
两者相比而言,getline()
简单容易使用,get()
则使得检查错误更简单一些。
5.clear()
clear()
方法用于重置错误输入标记。
通过cin.get(ch)
可以解决空白字符的输入,那么当输入内容和类型不匹配时如何处理呢?
先看下例:
#include <iostream>
const int Size = 5;
int main()
{
using namespace std;
int arr[Size];
int i = 0;
cout << "enter a num:";
while (i < Size)
{
cin >> arr[i];
i++;
}
for (int j = 0; j < i; j++)
cout << "arr[" << j << "] = " << arr[j] << endl;
system("pause");
return 0;
}
/**
运行:
enter a num:12
3
4
5
q
arr[0] = 12
arr[1] = 3
arr[2] = 4
arr[3] = 5
arr[4] = -858993460
/
可以看出,如果发生类型不匹配,则将停止输入。
假设有如下代码:
int n;
cin >> n;
在发生类型不匹配时,将发生四种情况:
- 1.n的值保持不变;
- 2.不匹配的数据将被留在输入队列中;
- 3.cin对象中的一个错误标记被设置;
- 4.对cin方法的调用将返回false(如果需要bool类型)。
当cin对象中设置了错误标记后,将停止输入,必须重置该标记后才可以继续输入。
当程序读取错误时,cin将停止读取,那么如何可以让它继续读取呢?如果需要这样做,则应实现以下三个步骤:
- 1.重置cin已接收新的输入;
- 2.将错误的输入删除;
- 3.提示用户继续输入。
下面示例演示了如上这些工作:
#include <iostream>
const int Max = 5;
int main6()
{
using namespace std;
int golf[Max];
cout << "Please enter your golf scores" << endl;
int i = 0;
for (; i < Max; i++)
{
cout << "round #"<< i+1 <<": ";
while (!(cin >> golf[i]))//当出现输入错误时
{
cin.clear();//重置错误标记
while (cin.get() != '\n')//清空错误输入
{
continue;
}
//提示用户
cout << "please enter a number" << endl;
}
}
double total = 0L;
for (int j = 0; j < i; j++)
{
total += golf[j];
}
cout << total / Max << " average score " << Max << " rounds " << endl;
system("pause");
return 0;
}
/**
运行:
Please enter your golf scores
round #1: 12
round #2: wq
please enter a number
123
round #3: sdf
please enter a number
3
round #4: 3
round #5: 4
29 average score 5 rounds
/
结合上面的示例可得:
对于operator >>
:
- 1.将忽略空白符;
- 2.发送给cin的数据被缓冲,只有在按下Enter后,输入内容才会发送给程序;
- 3.不清空输入队列;
- 4.读取错误时,cin设置错误标记。
对于get(char& ch)
:
- 1.不会忽略空白字符;
- 2.发送给cin的数据被缓冲,只有在按下Enter后,输入内容才会发送给程序;
- 3.不清空输入队列;
- 4.读取错误时,cin设置错误标记。
对于get(char_type* s, streamsize n)
:
- 1.以行为单位读取字符串,通过换行符来确定行尾,不会丢弃换行符,而是会保留在输入队列中;
- 2.如需清除换行符,需要再调用
get()
。
对于getline(char_type* s, streamsize n )
:
- 1.以行为单位读取字符串,通过换行符来确定行尾,并丢弃换行符,因此不需手动清理换行符。
总结
- 1.如果读取数字,只能使用
cin >> num
; - 2.如果读取字符,可以使用
cin >> ch
和cin.get(char)
; - 3.如果按行读取,则应使用
cin.get(char[],size).get()
或者cin.getline(char[],size)
; - 4.
cin.get()
可用于清空换行符; - 5.将cin用于测试条件中时,如果输入错误,讲返回false,因此可以以如
while(cin.get())
的方式使用cin。