簡體   English   中英

std::istream::sentry 與 std::istream 的使用

[英]Use of std::istream::sentry with std::istream

考慮以下簡單程序,該程序將輸入拆分為空白並每行打印一個非空白標記:

#include <iostream>
int main(int argc, char* argv[])
{
        while (std::cin)
        {
                std::string s;
                std::cin >> s;
                std::cout << "-" << s << "-\n";
        }
        return 0;
}

這工作正常 - 除了因為輸入流僅我們嘗試從中讀取后才指示 EOF,當它到達輸入流( ^D )的末尾時,它會讀入並發出一個空字符串:

[begin]
< a b c
> -a-
> -b-
> -c-
< (^D)
> --
[end]

我們可以通過使輸出行以!s.empty()條件來解決這個問題。

然而,還有另一種選擇。 我們可以替換該行:

while (std::cin)

和:

while (std::istream::sentry(std::cin))

sentry 對象(通常由operator>>內部使用)具有消耗空格然后檢查 EOF 或其他流狀態的效果:

[begin]
< a b c
> -a-
> -b-
> -c-
< (^D)
[end]

我的問題有三個:

  • 有什么理由說明這個結構不能按預期工作嗎?
  • 它已經是慣用語了嗎?
  • 如果沒有,為什么不呢?

std::istream::sentry用於輸入函數內部 解決您的問題的正確方法是始終檢查流是否良好,即讀取讀取成功:

for (std::string s; std::cin >> s; ) {
    std::cout << '-' << s << "-\n";
}

流無法在讀取之前知道讀取操作是否會成功。 完成后,它就知道了。

使用sentry的方法通常適用於字符串,但對於需要任何格式的類型可能會失敗。 例如,如果您需要讀取一個int跳過與sentry的空格並不表示是否可以讀取一個int 即使使用std::string該方法也可能失敗:流可以在第一次訪問時提供一個字符,但在第二次訪問時失敗。 第一次訪問是確定字符不是來自sentry的構造函數的空格,然后是從字符串讀取失敗。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM