2014年9月16日 星期二

善用 C++ istream 的 eof() 和 fail()

當函式需要讀入資料做處理時, 讓函式接收一個 std::istream* 會比直接呼叫 std::cin 好一些, 必要時可以改傳 std::istringstream 提供更多彈性, 比方說方便作測試。

不過實測的結果, std::cin 和 std::istringstream 的行為略有不同。std::cin 讀到 EOF 後, 呼叫 eof() 才會回傳 true, 但是 std::istringstream 在讀完最後一個 byte 後, eof() 就回傳 true 了。

以下是一個小範例, 可以正確處理兩者, 關鍵是讀完資料後用 fail() 檢查剛才的輸入是否有效。

#include <iostream>
#include <sstream>

void foo(std::istream* s)
{
  int n;
  while (!s->eof()) {
    *s >> n;
    if (!s->fail()) {
      std::cout << n << std::endl;
    }
  }
}

int main(void)
{
  std::istringstream ss("1 2 3 4 5");
  foo(&ss);
  foo(&std::cin);
  return 0;
}

另外附上別人截錄的官方說明。

沒有留言:

張貼留言

在 Fedora 下裝 id-utils

Fedora 似乎因為執行檔撞名,而沒有提供 id-utils 的套件 ,但這是使用 gj 的必要套件,只好自己編。從官網抓好 tarball ,解開來編譯 (./configure && make)就是了。 但編譯後會遇到錯誤: ./stdio.h:10...