[C++] cin.get(),cin.getline(),cin.clear()使用技巧

cin是用于输入的istream类的一个对象使用cin进行输入时,程序将输入视为一系列的字符,然后cin对象才负责将字符转换为其他类型。在输入数据时,可使用cin >> chcin.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 >> chcin.get(char);
  • 3.如果按行读取,则应使用cin.get(char[],size).get()或者cin.getline(char[],size);
  • 4.cin.get()可用于清空换行符;
  • 5.将cin用于测试条件中时,如果输入错误,讲返回false,因此可以以如while(cin.get())的方式使用cin。
  • 18
    点赞
  • 53
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值