C++标准I/O返回值问题

这里以标准输入流cin为例。

首先cin是一个对象,不会“返回”值,>>和<<才是方法,具有返回值。>>和<<操作符的运算顺序是从左向右,所以下面两种语句描述其实是一致的:

cin >> a >> b >> c;
(((cin >> a) >> b) >> c)

操作cin >> a的意义:调用istream的operator>>方法读取数据并存入变量a中。那么>>或者<<的返回值是什么呢?这里说的返回值并不是指读入变量中的值,而是返回赋给左值的数据,在这里,>>返回的是cin,追踪源码可以发现这一点:

istream& operator>> (istream& is, char& ch );
istream& operator>> (istream& is, signed char& ch );
istream& operator>> (istream& is, unsigned char& ch );
istream& operator>> (istream& is, char* str );
istream& operator>> (istream& is, signed char* str );
istream& operator>> (istream& is, unsigned char* str );

当然,也可以测试如下:

int main()
{
	int a;

	if ((cin >> a) == cin)
	{
		cout << "Equal" << endl;
	}
	else
	{
		cout << "Not equal" << endl;
	}

	return 0;
}

为什么可以使用cin作为真值判定条件?

cin可以被如下使用:

if (cin) {}
if (cin >> a >> b) {}
while (cin >> a) {}

上面说到了>>返回值是cin,所以上面的真值判定等同于:

if (cin) {}
if (cin) {}
while (cin) {}

如果cin的状态OK则为真,如果cin遇到eof或者发生错误则返回false,为什么可以使用cin作为真值判定条件呢?

首先看cin是如何定义的:

extern istream cin;

这样一个值怎么可以作为if的真值判定条件呢?这是因为所有派生自ios的类都可以被强制转换为一个void *指针,如果设置了错误标志位则指针被置为NULL,否则为非NULL。测试代码如下:

#include <iostream>
#include <fstream>
#include <string>

using namespace std;

int main()
{
	cout << "test1:" << endl;
	int a;
	if (cin >> a)
	{
		cout << "True" << endl;
	}
	else
	{
		cout << "False" << endl;
	}
	
	cout << "test2:" << endl;
	ifstream is1, is2;
	is1.open("test.txt");
	is2.open("test.txt", ifstream::app);

	if ((void *)is1 == NULL)
		cerr << "Error open file" << endl;
	else
		cout << "success: is1=" << is1 << endl;

	if ((void *)is2 == NULL)
		cerr << "Error open file" << endl;
	else
		cout << "success: is2=" << is2 << endl;
	
	return 0;
}

编译后执行结果:

allan@ubuntu:Temp$ ./a.out 
test1:
a  						# 输入a,不是整数,所以cin出错,应该为NULL
False
test2:
Error open file			# 文件不存在,打开失败
success: is2=0x7ffffe090dd0		# 文件不存在,创建文件;打开成功

allan@ubuntu:Temp$ ./a.out 
test1:
1
True
test2:
Error open file
success: is2=0x7fffcf46f320

参考自:http://www.cnblogs.com/alex-tech/archive/2012/03/27/2420197.html


添加新评论

选择表情 captcha

友情提醒:不填或错填验证码会引起页面刷新,导致已填的评论内容丢失。

|