C++ ifstream 类

定义和用法

ifstream 类(即 "input file stream" 的缩写)用于从文件中读取数据。

ifstream 类定义在 <fstream> 头文件中。

要打开文件,请将文件路径传递给构造函数:

ifstream MyReadFile("filename.txt");

ifstream 类有多种方式从文件中读取数据。一种简单的方法是使用 getline() 函数读取直到下一行换行符的所有字符,并将它们写入一个字符串中。

从文件中输出一行文本:

string myText;
getline(MyReadFile, myText);
cout << myText;

实例

使用 ifstream 从文件中读取行:

// 创建一个文本字符串,用于输出文本文件
string myText;

// 从文本文件中读取
ifstream MyReadFile("filename.txt");

// 使用 while 循环和 getline() 函数逐行读取文件
while (getline(MyReadFile, myText)) {
  // 输出文件中的文本
  cout << myText;
}

// 关闭文件
MyReadFile.close();

文件读取函数

文件读取函数从文件中提取字符并移动文件指针。

get()

get() 方法从文件中读取单个字符,并以 int 值的形式返回其 ASCII 值。将其转换为 char 类型以查看字符。文件指针移动到文件中的下一个字符。

char myChar = MyReadFile.get();
cout << myChar;

get(destination, size, delimiter) 方法从文件中读取最多 size 个字符,并将其写入目标位置。它一旦遇到换行符、文件结尾或可选的由 delimiter 参数给定的字符,就会停止读取。写入目标位置的值始终以 \0 空终止字符结尾。此方法将文件指针移动到停止读取的换行符或分隔符处。

char destination[20];
MyReadFile.get(destination, 20);
cout << destination << "\n";

// 当遇到 '.' 时停止读取
MyReadFile.get(destination, 20, '.');
cout << destination << "\n";

getline()

getline(destination, size, delimiter) 方法与 get(destination, size, delimiter) 方法相同,只是换行符或分隔符被丢弃,且文件指针移动到紧随其后的字符。

char destination[20];
MyReadFile.getline(destination, 20);
cout << destination << "\n";

// 当遇到 '.' 时停止读取
MyReadFile.getline(destination, 20, '.');
cout << destination << "\n";

还有一个类似的 getline(stream, destination, delimiter) 函数,它从由 ifstream 对象的 stream 参数指定的文件中读取所有字符,直到下一个换行符(或可选的分隔符),并将它们写入由 destination 指定的字符串中。

string destination;
getline(MyFile, destination);
cout << destination << "\n";

// 当遇到 '.' 时停止读取
getline(MyFile, destination, '.');
cout << destination << "\n";

read()

read(destination, n) 方法从文件中读取 n 个字符,并将它们写入由 destination 参数指定的字符数组中。与其他函数不同,它不会在换行符处停止读取,也不会在数据中添加空终止字符。

char destination[20];
MyReadFile.read(destination, 19);
destination[20] = '\0'; // 确保以空终止字符结尾
cout << destination << "\n";

peek()

peek() 方法从文件中读取单个字符,并以 int 值的形式返回其 ASCII 值。将其转换为 char 类型以查看字符。与 get() 方法不同,此方法不会移动文件指针。

char myChar = MyReadFile.peek();
cout << myChar;

gcount()

gcount() 方法返回最近调用的文件读取方法从文件中提取的字符数。

char destination[20];
MyReadFile.getline(destination, 20);
cout << MyReadFile.gcount() << "\n";

文件处理函数

文件处理函数用于打开、关闭和导航文件。

open()

open(filepath) 方法打开由 filepath 指定的路径处的文件。如果文件已经打开,则此方法无效。

ifstream MyReadFile;
MyReadFile.open("filename.txt");

is_open()

is_open() 方法如果文件已打开,则返回 true;如果没有文件打开,则返回 false。

ifstream MyReadFile;
cout << MyReadFile.is_open(); << "\n"; // 显示 0,因为文件未打开
MyReadFile.open("filename.txt");
cout << MyReadFile.is_open(); << "\n"; // 显示 1,因为文件已打开

close()

close() 方法关闭文件。完成文件操作后关闭文件以释放资源是个好习惯。

MyReadFile.close();

rdbuf()

rdbuf() 方法返回一个指向直接处理文件的内部 filebuf 对象的指针。

filebuf * buf = MyReadFile.rdbuf();

unget()

unget() 方法将文件指针向后移动一个字符。

使用 unget() 方法打印同一个字符两次:

char myChar = MyReadFile.get();
cout << myChar << "\n";
MyReadFile.unget();
myChar = MyReadFile.get();
cout << myChar;

seekg()

seekg(position) 方法将文件指针移动到相对于文件开头的指定位置。

MyReadFile.seekg(6)

seekg(position, origin) 方法将文件指针移动到相对于给定原点的文件中指定位置。origin 有三个可能的值:

  • ifstream::beg - 位置相对于文件开头
  • ifstream::cur - 位置相对于当前文件位置
  • ifstream::end - 位置相对于文件结尾

将文件指针移动到不同位置:

MyReadFile.seekg(6, ifstream::beg);
cout << MyReadFile.tellg(); << "\n";
MyReadFile.seekg(-3, ifstream::cur);
cout << MyReadFile.tellg(); << "\n";
MyReadFile.seekg(-4, ifstream::end);
cout << MyReadFile.tellg(); << "\n";

tellg()

tellg() 方法返回文件中文件指针的当前位置。

cout << MyReadFile.tellg();

提取运算符 (>>)

提取运算符 (>>) 从文件的当前位置读取一定数量的字符,将其解释并将解释后的值写入变量中。然后,文件指针会移动到下一个尚未读取的字符。字符的解释方式取决于变量的数据类型。

语法

MyReadFile >> variable

它也可以多次使用,以逐个读取文件的部分内容:

MyReadFile >> variable1 >> variable2 >> variable3

提取运算符 (>>) 首先会跳过空白字符(空格、制表符和换行符),直到遇到第一个非空白字符。之后,它会根据变量的数据类型按照以下表格中的规则进行读取。

数据类型 描述 示例
  • int
  • long
  • short

读取一个数字序列并将其解释为整数。

序列前可以有一个符号(+ 或 -)。

读取会在遇到第一个非数字字符时停止。

如果未找到有效的序列,ifstream 对象将失败并停止进一步读取。

  • 15
  • +125
  • -30
bool

以与上述相同的方式读取一个整数,然后将 0 解释为 false,将 1 解释为 true。

任何其他整数值也会被解释为 true,但 ifstream 对象将失败并停止进一步读取。

下一节中描述的 boolalpha 操纵符会完全改变此行为。

  • 0
  • 1
  • +01
  • float
  • double

读取一个有效的字符序列并将其解释为浮点数。

有效的序列至少包含一个数字,前面可以有一个符号(+ 或 -),后面可以跟一个小数点和十进制数字。

科学计数法(数字后跟 e 或 E 和一些数字)也可以使用。

如果未找到有效的序列,ifstream 对象将失败并停止进一步读取。

  • 5
  • -5.46
  • +2e4
  • -1.62E-5
char

从文件中读取单个字符。

如果文件指针位于文件末尾,ifstream 对象将失败并停止进一步读取。

B
  • string
  • char *

读取所有字符,直到下一个空白字符(空格、制表符或换行符)、空终止字符或文件末尾。

变量值将添加一个 \0 空终止字符。

如果文件指针已经位于空终止字符或文件末尾,ifstream 对象将失败并停止进一步读取。

Hello

操纵符

操纵符可以代替变量使用。当使用操纵符时,它们会改变 ifstream 对象解释数据的方式。操纵符的效果会一直保持,直到另一个操纵符改变它。

以下表格列出了 ifstream 对象可以使用的操纵符。

操纵符 描述
noskipws

提取运算符 (>>) 不会跳过空白字符,而是会读取它们。

这主要用于 char 类型的变量,因为对于其他数据类型,遇到空白字符时会停止读取。

skipws 重置 noskipws 操纵符所做的更改。
ws 将文件指针移动到文件中下一个非空白字符的位置。
hex 在使用整数变量时,期望数字的十六进制表示(数字 0 到 9 和 A 到 F)。
oct 在使用整数变量时,期望数字的八进制表示(数字 0 到 7)。
dec

在使用整数变量时,期望数字的十进制表示(数字 0 到 9)。

这会重置 hex 和 oct 操纵符所做的更改。

boolalpha 在为布尔变量读取数据时,不再查找整数,而是查找字符序列 "true" 或 "false"。
noboolalpha 重置 boolalpha 操纵符所做的更改。

实例

使用操纵符改变数据解释方式:

ifstream MyFile("example.txt");
bool myBool;
int myInt;

// 将字符序列 "true" 和 "false" 解释为布尔值
MyFile >> boolalpha >> myBool;

// 恢复为正常读取布尔值
MyFile >> noboolalpha;

// 从文件中读取十六进制数字并将其解释为整数
MyFile >> hex >> myInt;

// 恢复为正常读取整数
MyFile >> dec;

MyFile.close();
return 0;