從檔案中讀取

有幾種方法可以從檔案中讀取資料。

如果你知道資料的格式,可以使用流提取運算子(>>)。假設你有一個名為 foo.txt 的檔案,其中包含以下資料:

John Doe 25 4 6 1987
Jane Doe 15 5 24 1976

然後,你可以使用以下程式碼從檔案中讀取該資料:

// Define variables.
std::ifstream is("foo.txt");
std::string firstname, lastname;
int age, bmonth, bday, byear;

// Extract firstname, lastname, age, bday month, bday day, and bday year in that order.
// Note: '>>' returns false if it reached EOF (end of file) or if the input data doesn't
// correspond to the type of the input variable (for example, the string "foo" can't be
// extracted into an 'int' variable).
while (is >> firstname >> lastname >> age >> bmonth >> bday >> byear)
    // Process the data that has been read.

流提取運算子 >> 提取每個字元,如果找到無法儲存的字元或者是特殊字元,則停止:

  • 對於字串型別,運算子在空格( )或換行符(\n)處停止。
  • 對於數字,運算子停止在非數字字元處。

這意味著以前版本的檔案 foo.txt 也將被前面的程式碼成功讀取:

John 
Doe 25
4 6 1987

Jane
Doe 
15 5
24
1976

流提取運算子 >> 始終返回給定的流。因此,可以將多個運算子連結在一起以便連續讀取資料。但是,流也可以用作布林表示式(如前面程式碼中的 while 迴圈所示)。這是因為流類具有 bool 型別的轉換運算子。只要流沒有錯誤,此 bool() 運算子將返回 true。如果流進入錯誤狀態(例如,因為無法提取更多資料),則 bool() 運算子將返回 false。因此,在讀取輸入檔案結束後,將退出前一程式碼中的 while 迴圈。

如果你希望將整個檔案作為字串讀取,可以使用以下程式碼:

// Opens 'foo.txt'.
std::ifstream is("foo.txt");
std::string whole_file;

// Sets position to the end of the file.
is.seekg(0, std::ios::end);

// Reserves memory for the file.
whole_file.reserve(is.tellg());

// Sets position to the start of the file.
is.seekg(0, std::ios::beg);

// Sets contents of 'whole_file' to all characters in the file.
whole_file.assign(std::istreambuf_iterator<char>(is),
  std::istreambuf_iterator<char>());

此程式碼為 string 保留空間,以減少不必要的記憶體分配。

如果要逐行讀取檔案,可以使用 getline() 函式 :

std::ifstream is("foo.txt");   

// The function getline returns false if there are no more lines.
for (std::string str; std::getline(is, str);) {
    // Process the line that has been read.
}

如果要讀取固定數量的字元,可以使用流的成員函式 read()

std::ifstream is("foo.txt");
char str[4];

// Read 4 characters from the file.
is.read(str, 4);

執行讀取命令後,應始終檢查是否已設定錯誤狀態標誌 failbit,因為它指示操作是否失敗。這可以通過呼叫檔案流的成員函式 fail() 來完成:

is.read(str, 4); // This operation might fail for any reason.

if (is.fail())
    // Failed to read!