从文件中读取

有几种方法可以从文件中读取数据。

如果你知道数据的格式,可以使用流提取运算符(>>)。假设你有一个名为 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!