如果我这样做:
ifstream stream("somefilewhichopenssuccesfully.txt");
string token;
if( stream >> token )
cout << token;
else
cout << token;
第二种情况下的输出是否保证为空字符串?我似乎无法在cplusplus.com上找到答案。
谢谢!
答案 0 :(得分:2)
第二种情况下的输出是否保证为空字符串?
答案是:不,因为它取决于,如下所述。
由于只有在尝试从流中读取失败时才会执行else
块,并且在读取过程中可能会发生这种情况。
如果在第一次尝试时失败,则流中没有字符提取,因此token
将为空(原样)。
如果在几次读取后失败,则token
将不为空。它将包含到目前为止从流中成功读取的字符。
标准中的§21.3.7.9部分说明,
通过构建一个哨兵对象开始 k好像k是由typename构造的 basic_istream ::哨兵 K(是)。如果bool(k)为真,则调用 str.erase()然后提取 来自的字符并将它们附加到 str就像调用str.append(1,c)一样。 如果is.width()大于零, 最大字符数n 附加的是is.width();否则n是 str.max_size()。 字符是 提取并附加到任何一个 发生以下情况:
- n个字符 存储;
- 发生文件结束 输入序列;
- isspace(c,is.getloc())为true 下一个可用的输入字符c。
在最后一个字符(如果有)之后 提取,is.width(0)被调用 哨兵对象k被摧毁。
如果函数没有提取任何字符,则调用is.setstate(ios :: failbit),这可能会抛出ios_base :: failure(27.4.4.3)。
另请注意,标准中的第21.3.1 / 2节保证默认构造的字符串为空。标准说它的大小将为零,这意味着空。
答案 1 :(得分:1)
我删除了原来的答案,因为我想测试一下。这就是我所看到的,如果在阅读时出现错误(在此上下文中不计算EOF),则修改原始字符串并且分支看到修改后的版本。为了测试我做了以下操作,创建了一个2Gb文件(touch
然后truncate
),上面的代码要阅读。代码运行时,删除了文件(这应该设置failbit
- 我认为)。立即停止阅读,但字符串被修改 - 它的大小更大。
对我来说,这表明即使流操作失败,字符串也会被修改。
答案 2 :(得分:0)
不,即使操作失败,该字符串也将包含到目前为止提取的字符。
标准说(§21.4.8.9):
效果:表现为格式化输入功能(27.7.2.2.1)。构建
sentry
对象后,如果哨兵转换为true,则调用str.erase()
,然后从is
中提取字符并将其附加到str
,就好像通过调用str.append(1,c)
一样}。如果is.width()
大于零,则附加的字符的最大数量n为is.width()
;否则n是str.max_size()
。提取并附加字符,直到出现以下任何一种情况:
- 存储n个字符;
- 输入序列上出现文件结尾;
-isspace(c,is.getloc())
对于下一个可用输入字符c为真。