cin、cin.get()、getline()详解

int main()
{
	char str[8];
	cin.getline(str, 5);
	cout << str << endl;
	cin.getline(str, 5);
	cout << str << endl;
	return 0;
}

 

       程序执行情况:

       测试一:abcd (回车)abcd (输出)efgh(回车)efgh (输出)当用户第一次输入的字符串字符数小于4时,程序执行正常!

       测试二:abcdefgh (回车)abcd (输出)    (输出-换行)当用户第一次输入的字符数字符数大于4时,第一个字符串接受输入的前四个字符,而第二次的输入操作没有执行,第二个字符串输出为空。(getline超长检测,不会执行之后的cin)

 

1、cin >>

cin>>输入操作符是根据后面变量的类型读取数据。输入结束条件  :遇到Enter、Space、Tab键。(这个很重要!)对结束符的处理 :当第一个字符为分隔符时丢弃缓冲区中的结束符,当还存在其他cin输入时,会输出下一个非结束符字符串数据。

 

重要:当cin>>从缓冲区中读取数据时,若缓冲区中第一个字符是空格、tab或换行这些分隔符时,cin>>会将其忽略并清除,继续读取下一个字符,若缓冲区为空,则继续等待。但是如果读取成功,字符后面的分隔符是残留在缓冲区的,cin>>不做处理理解

int main()
{
	char str1[10], str2[2];
	cin >> str1;
	cin >> str2;
	cout << str1 << endl;
	cout << str2 << endl;
	return 0;
}

注意:

  1. 在测试用例的时候发现一个问题,就是当输入长度大于实际数组长度的时候,\0的位置并不在str[length-1]的位置,会在(str+输入字符长度-1)的位置,所以在输出str的时候,str的字符数组长度并不是定义的length,而是输入字符长度reallentth。

当输入两字符数组时,输入长度小于数组定义长度,两数组正常输出。但是当输入长度大于数组定义长度时,遇到一个问题就是str1数组内的数据被重写了。根究发现,系统分配的地址空间str1在后,而 str2在前,当str读取的数据长度使得str2数据地址和str1的数据地址重叠,就有可能导致str1数据重写。以下是分析代码:

 

int main()
{
	char str1[10], str2[2];
	for (int i = 0; i < 10; i++)
	{
		cout << (void*)(str1+i) << endl;
	}

	for (int j = 0; j < 2; j++)
	{
		cout << (void*)(str2 + j) << endl;
	}
	cin >> str1;
	cin >> str2;
	cout << str1 << endl;
	cout << str2 << endl;
	return 0;
}

输出:

cin、cin.get()、getline()详解_第1张图片

 

2、cin.get()

该函数有三种格式:无参,一参数,二参数即cin.get(),cin.get(char ch), cin.get(array_name, Arsize) 读取字符的情况:输入结束条件:Enter键对结束符处理:不丢弃缓冲区中的Enterspace和TAB(重要)cin.get()与cin.get(char ch)用于读取字符,他们的使用是相似的,即:ch=cin.get()与cin.get(ch)是等价的。

cin.get(array_name, Arsize)是用来读取字符串的,可以接受空格字符,遇到Enter结束输入,按照长度(Arsize)读取字符, 会丢弃最后的Enter字符重要,但是不丢弃SPACE和TAB

 

3、cin.getline()

cin.getline()与 cin.get(array_name,Arsize)的读取方式差不多,以Enter结束,可以接受空格字符。按照长度(Arsize)读取字符, 会丢弃最后的Enter字符。但是这两个函数是有区别的:cin.get(array_name, Arsize)当输入的字符串超长时,不会引起cin函数的错误,后面的cin操作会继续执行,只是直接从缓冲区中取数据。但是cin.getline()当输入超长时,会引起cin函数的错误,后面的cin操作将不再执行。 

 

4、cin错误函数

 

cin的错误处理机制,并且学习几个重要的函数:cin.fail(), cin.bad(), cin.good(), cin.clear(), cin.ignore()等。

ios::badbit    001   输入(输出)流出现致命错误,不可挽回 

ios::eofbit    010   已经到达文件尾

ios::failbit   100   输入(输出)流出现非致命错误,可挽回 

ios::goodbit   000   流状态完全正常, 各异常标志位都为0

相应的函数1 or true if rdstate & XXbit is nonzero; otherwise 0。

 cin.clear()的作用是重置错误标志。

int main()
{
	char ch, str[20];
	cin.getline(str, 5);
	cout << "flag1:" << cin.good() << endl;   // 查看goodbit状态,即是否有异常
	cin.clear();                        // 清除错误标志
	cout << "flag1:" << cin.good() << endl;   // 清除标志后再查看异常状态
	cin >> ch;
	cout << "str:" << str << endl;
	cout << "ch :" << ch << endl;
	return 0;
}

重置错误标志还不够!要是能将缓冲区的残留数据清空了就好了哦!下面我们再来看一个很重要的函数!

basic_istream&ignore(streamsize _Count = 1, int_type _Delim = traits_type::eof());

这个函数用来丢弃输入缓冲区中的字符,第一参数定义一个数,第二个参数定义一个字符变量。下面解释一下函数是怎样执行的:函数不停的从缓冲区中取一个字符,并判断是不是_Delim,如果不是则丢弃并进行计数,当计数达到_Count退出,如果是则丢弃字符退出。例:cin.ignore(5, 'a'); 函数将不断从缓冲区中取一个字符丢弃,直到丢弃的字符数达到5或者读取的字符为'a'。

你可能感兴趣的:(C++基础)