从 istream 提取失败后的字符串内容

发布于 2024-11-01 18:22:40 字数 262 浏览 0 评论 0原文

如果我这样做:

ifstream stream("somefilewhichopenssuccesfully.txt");
string token;
if( stream >> token )
    cout << token;
else
    cout << token;

第二种情况的输出是否保证为空字符串?我似乎无法在 cplusplus.com 上找到这个问题的答案。

谢谢!

If I do this:

ifstream stream("somefilewhichopenssuccesfully.txt");
string token;
if( stream >> token )
    cout << token;
else
    cout << token;

Is the output in the second case guaranteed to be an empty string? I can't seem to find the answer to this on cplusplus.com.

Thanks!

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(3

鹿港小镇 2024-11-08 18:22:40

第二种情况的输出是否保证为空字符串?

答案是:不,因为这取决于情况,如下所述。

因为只有当尝试从流中读取失败时才会执行 else 块,并且这种情况可能在读取过程中的任何时候发生。

  • 失败,则不会从流中提取字符,因此 token 将为空(就像以前一样)。

  • 如果在几次读取后失败,那么token将不为空。它将包含迄今为止从流中成功读取的字符。

标准第 §21.3.7.9 节规定,

首先构造一个哨兵对象
k 就好像 k 是由类型名构造的
basic_istream::哨兵
k(是)。如果 bool(k) 为 true,则调用
str.erase() 然后提取
来自 is 的字符并将它们附加到
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 节保证默认构造的字符串将为空。标准说它的大小将为零,这意味着,空的。

Is the output in the second case guaranteed to be an empty string?

The answer is : no, because it depends, as described below.

Since else block will be executed only if an attempt to read from the stream fails, and that can occur anytime in the course of reading.

  • If it fails at the very first attempt, then there is no character extraction from the stream, and hence token will be empty (as it was).

  • If it fails after few reads, then token will not be empty. It will contain the characters successfully read so far from the stream.

The section §21.3.7.9 from the Standard says,

Begins by constructing a sentry object
k as if k were constructed by typename
basic_istream::sentry
k(is). If bool(k) is true, it calls
str.erase() and then extracts
characters from is and appends them to
str as if by calling str.append(1,c)
.
If is.width() is greater than zero,
the maximum number n of characters
appended is is.width(); otherwise n is
str.max_size(). Characters are
extracted and appended until any of
the following occurs
:

— n characters
are stored;

— end-of-file occurs on
the input sequence;

— isspace(c,is.getloc()) is true for the
next available input character c.

After the last character (if any) is
extracted, is.width(0) is called and
the sentry object k is destroyed.

If the function extracts no characters, it calls is.setstate(ios::failbit), which may throw ios_base::failure (27.4.4.3).


Also note that the section §21.3.1/2 from the Standard guarantees that the default constructed string will be empty. The Standard says its size will be zero, that means, empty.

鸠魁 2024-11-08 18:22:40

我删除了原来的答案,因为我想测试一下。这就是我所看到的,如果读取时出现错误(在此上下文中不计算 EOF),原始字符串将被修改,分支将看到修改后的版本。为了测试,我执行了以下操作,创建了一个 2Gb 文件(touch 然后 truncate),读取上面的代码。当代码运行时,删除该文件(这应该设置failbit - 我认为)。立即停止读取,但字符串被修改 - 它具有更大的大小。

对我来说,这表明即使流操作失败,字符串也会被修改。

I deleted my original answer because I wanted to test this. This is what I see, if there is an error whilst reading (EOF is not counted in this context), the original string is modified and the branch sees the modified version. To test I did the following, created a 2Gb file (touch then truncate), the above code to read. Whilst the code was running, removed the file (this should set the failbit - I think). Immediately stops reading, but the string is modified - it has a larger size.

To me this indicates that the string is modified even if the stream operation fails.

小糖芽 2024-11-08 18:22:40

不会,即使操作失败,字符串也会包含到目前为止提取的字符。

该标准规定(§21.4.8.9):

效果:表现为格式化输入函数 (27.7.2.2.1)。构造完 sentry 对象后,如果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 为 true。

No, even if the operation fails, the string will contain the characters extracted so far.

The standard says (§21.4.8.9):

Effects: Behaves as a formatted input function (27.7.2.2.1). After constructing a sentry object, if the sentry converts to true, calls str.erase() and then extracts characters from is and appends them to str as if by calling str.append(1,c). If is.width() is greater than zero, the maximum number n of characters appended is is.width(); otherwise n is str.max_size(). Characters are extracted and appended until any of the following occurs:
— n characters are stored;
— end-of-file occurs on the input sequence;
isspace(c,is.getloc()) is true for the next available input character c.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文