
在 C++ 编程中,输入输出(IO)操作是与外部世界交互的基础。C++ 标准库提供了一套强大且灵活的面向对象的 IO 库,能够方便地进行各种输入输出操作,无论是从控制台读取数据,还是写入数据到文件,亦或是在网络通信中处理数据传输。
流是 C++ IO 库的核心概念。可以将流看作是一个字符序列的抽象表示,数据从数据源(如文件、键盘等)流入程序,或者从程序流出到数据目的地(如文件、显示器等)。在 C++ 中,有三种基本类型的流:输入流(istream)用于从外部读取数据,输出流(ostream)用于向外部写入数据,以及既可以读又可以写的流(iostream)。
①流类层次结构
ios_base
▲
│
basic_ios<charT, traits>
▲ ▲ ▲
│ │ │
basic_istream────┤ │ ├─────basic_ostream
▲ │ ▲
│ │ │
basic_iostream───────┤ │ ├───────────┤
▼ ▼ ▼
ifstream iostream ofstream
istringstream ostringstreamC++标准库定义了三个基础流类:
ios)ios)istream和ostream)派生类包括:
②核心组件概览
iostream: 控制台输入输出
fstream: 文件流操作
sstream: 字符串流处理
iomanip: 格式化控制工具
C++ 标准库预定义了几个重要的流对象,方便进行常见的 IO 操作:
int num;
cin >> num;从键盘读取一个整数并存储到num变量中。
cout << "Hello, World!" << endl;将字符串 “Hello, World!” 输出到控制台,并换行。endl是一个操纵符,用于插入换行符并刷新输出缓冲区。
cerr << "An error occurred!" << endl;插入操作符用于向输出流中写入数据。可以用于输出各种数据类型,包括基本数据类型(如int、double、char等)和字符串。例如:
int a = 10;
double b = 3.14;
string str = "Hello";
cout << "a = " << a << ", b = " << b << ", str = " << str << endl;依次将变量a、b和字符串str的值输出到控制台。
提取操作符用于从输入流中读取数据。它会跳过输入流中的空白字符(如空格、制表符、换行符等),直到遇到第一个非空白字符,然后将数据读取到变量中。例如:
int x, y;
cout << "Enter two integers: ";
cin >> x >> y;
cout << "You entered x = " << x << " and y = " << y << endl;从控制台读取两个整数,分别存储到x和y变量中,并输出读取的值。
要将数据写入文件,我们使用ofstream(output file stream)类。首先需要包含<fstream>头文件。例如:
#include <fstream>
#include <iostream>
int main() {
std::ofstream outFile("example.txt");
if (outFile.is_open()) {
outFile << "This is a line of text written to the file." << std::endl;
outFile << "Another line." << std::endl;
outFile.close();
std::cout << "Data written to file successfully." << std::endl;
} else {
std::cerr << "Unable to open file." << std::endl;
}
return 0;
}
创建了一个名为example.txt的文件,并向其中写入两行文本。在写入完成后,使用close()方法关闭文件。
使用ifstream(input file stream)类从文件中读取数据。例如:
#include <fstream>
#include <iostream>
#include <string>
int main() {
std::ifstream inFile("example.txt");
if (inFile.is_open()) {
std::string line;
while (std::getline(inFile, line)) {
std::cout << line << std::endl;
}
inFile.close();
} else {
std::cerr << "Unable to open file." << std::endl;
}
return 0;
}
打开example.txt文件,并逐行读取文件内容,然后输出到控制台。getline()函数用于从输入流中读取一行数据,存储到line字符串中。
C++ 的文件流还支持随机访问文件,即可以在文件中任意位置进行读写操作。seekg()和seekp()函数分别用于输入流和输出流的定位,tellg()和tellp()函数用于获取当前位置。例如:
#include <fstream>
#include <iostream>
int main() {
std::fstream file("random.txt", std::ios::in | std::ios::out | std::ios::trunc);
if (file.is_open()) {
for (int i = 0; i < 10; ++i) {
file << i << " ";
}
file.seekp(5 * sizeof(int));
file << 99;
file.seekg(0);
int num;
while (file >> num) {
std::cout << num << " ";
}
file.close();
} else {
std::cerr << "Unable to open file." << std::endl;
}
return 0;
}
创建一个文件,写入 10 个整数,然后将文件指针移动到第 5 个整数的位置,修改该位置的值为 99,最后从文件开头读取并输出所有整数。
istringstream用于从字符串中读取数据,就像从输入流中读取一样。例如:
#include <sstream>
#include <iostream>
#include <string>
int main() {
std::string str = "10 3.14 Hello";
std::istringstream iss(str);
int num;
double dbl;
std::string word;
iss >> num >> dbl >> word;
std::cout << "num = " << num << ", dbl = " << dbl << ", word = " << word << std::endl;
return 0;
}
从字符串str中依次读取一个整数、一个双精度浮点数和一个字符串。
ostringstream用于将数据写入字符串,最终可以通过str()方法获取生成的字符串。例如:
#include <sstream>
#include <iostream>
#include <string>
int main() {
int a = 10;
double b = 3.14;
std::string str = "World";
std::ostringstream oss;
oss << "Hello, " << str << ", a = " << a << ", b = " << b;
std::string result = oss.str();
std::cout << result << std::endl;
return 0;
}
将各种数据类型组合成一个字符串并输出。
标志位 | 含义 | 检查方法 |
|---|---|---|
eofbit | 到达文件尾 | stream.eof() |
failbit | 操作失败(格式错误等) | stream.fail() |
badbit | 不可恢复的错误 | stream.bad() |
goodbit | 所有状态正常 | stream.good() |
#include <fstream>
#include <iostream>
using namespace std;
int main() {
ifstream file("nonexistent.txt");
if (!file) {
cerr << "错误: " << strerror(errno) << endl;
return 1;
}
// 设置异常掩码
file.exceptions(ifstream::failbit | ifstream::badbit);
try {
string line;
while (getline(file, line)) {
// 处理数据
}
} catch (const ios_base::failure& e) {
cerr << "IO异常: " << e.what() << endl;
}
return 0;
}ofstream ofs("large.txt");
ofs.rdbuf()->pubsetbuf(new char[1024*1024], 1024*1024); // 1MB缓冲区char buffer[4096];
while (ifs.read(buffer, sizeof(buffer))) {
// 处理4KB数据块
}ofstream ofs("log.txt", ios::app); // 追加模式
ifs.open("bigfile.bin", ios::binary | ios::ate); // 直接定位到文件尾#include <filesystem>
namespace fs = std::filesystem;
fs::path p = "data.txt";
if (fs::exists(p)) {
fs::remove(p);
}for (const auto& line : ifstream("data.txt")) {
process(line);
}C++ 标准 IO 库提供了丰富的功能和灵活的接口,通过流的概念,能够方便地进行各种输入输出操作。无论是简单的控制台输入输出,还是复杂的文件处理和字符串操作,都可以通过标准 IO 库高效地实现。掌握 C++ 标准 IO 库对于编写健壮、高效的 C++ 程序至关重要。
using声明在模板编程中有着重要应用,如定义模板类型别名等。