文章目录
C++IO流
定义
C++系统实现了一个庞大的类库,其中ios为基类,其他类都是直接或间接派生自ios类。
-
在ios类的基础上,派生出了两个主要的子类:istream(输入流)和 ostream(输出流)。它们分别用于处理输入和输出操作,并增加了一些特定的成员函数和操作符,使得输入输出更方便。
-
istream类和ostream类又进一步派生出了
iostream
类,它同时具有输入和输出的功能。iostream类继承了istream和ostream的特性,可以实现通用的输入输出操作。 -
另外,还有一些其他的IO流类,如ifstream(文件输入流)、ofstream(文件输出流)、stringstream(字符串流)等,它们都是直接或间接派生自ios类,通过添加额外的功能和操作来满足不同的需求。
C++标准IO流
C++标准库提供了以下流对象:
std::cin
:标准输入流,用于从控制台读取用户的输入。std::cout
:标准输出流,用于向控制台输出数据。std::cerr
:标准错误流,用于向控制台输出错误信息。std::clog
:标准日志流,用于向控制台输出程序的运行日志。
cin cout 的使用
std::cin
和 std::cout
是C++标准库中的输入输出流对象,用于从控制台读取用户输入和向控制台输出数据。
std::cin
用于输入操作,可以通过>>运算符从控制台读取不同类型的数据,例如整数、浮点数、字符串等
std::cout
用于输出操作,可以使用<<运算符将数据输出到控制台。
最常使用的输入输出流,以下是举例:
#include <iostream>
using namespace std;
void test_cin_cout() {
int num;
cout << "Enter an integer: ";
cin >> num;
cout << "Entered an integer: " << num << endl;
}
执行结果:
cerr 的使用
std::cerr
是C++标准库中的标准错误流对象,用于向控制台输出错误信息。与std::cout
类似,std::cerr也可以使用<<运算符
将文本和其他数据类型输出到控制台。
void test_cerr()
{
int dividend;
std::cin >> dividend;
int divisor;
std::cin >> divisor;
if (divisor == 0) {
std::cerr << "错误:除数不能为零。" << std::endl;
return;
}
int result = dividend / divisor;
std::cout << "结果为:" << result << std::endl;
}
与 std::cout
不同的是,std::cerr
会立即将输出发送到控制台,而不像std::cout
那样缓冲输出。这对于在程序发生错误时及时输出错误信息是很有用的。
clog的使用
std::clog
是C++标准库中的标准日志流对象,用于向控制台输出程序的运行日志。与std::cout和std::cerr类似,std::clog也可以使用<<运算符将文本和其他数据类型输出到控制台。
void test_clog() {
std::clog << "开始运行程序..." << std::endl;
// 运行其他代码...
std::clog << "程序运行结束。" << std::endl;
}
在上述代码中,我们使用std::clog输出程序的开始信息和结束信息。通过将日志输出到std::clog而不是std::cout,可以将程序的运行日志与普通的输出分开,使其更容易阅读和记录。
另外,与std::cerr
相比,std::clog
也会立即将输出发送到控制台,并且默认情况下其输出会被缓冲,但它们都可以在需要时手动刷新缓冲区。
注意事项
- cin为缓冲流。键盘输入的数据保存在缓冲区中,当要提取时,是从缓冲区中拿。如果一次输入过多,会留在那儿慢慢用,如果输入错了,必须在回车之前修改,如果回车键按下就无法挽回了。只有把输入缓冲区中的数据取完后,才要求输入新的数据。
- 输入的数据类型必须与要提取的数据类型一致,否则出错。出错只是在流的状态字state中对应位置位(置1),程序继续。
- 空格和回车都可以作为数据之间的分格符,所以多个数据可以在一行输入,也可以分行输入。但如果是字符型和字符串,则空格(ASCII码为32)无法用cin输入,字符串中也不能有空格。回车符也无法读入。
cin
和cout
可以直接输入和输出内置类型数据,原因:标准库已经将所有内置类型的输入和输出全部重载了- 对于自定义类型,如果要支持cin和cout的标准输入输出,需要对<<和>>进行重载。
C++ 文件IO流
C++提供了一组用于文件输入输出的标准库类,称为文件IO流。主要有以下三个类:
std::ifstream
:用于从文件中读取数据的输入文件流。std::ofstream
:用于向文件中写入数据的输出文件流。std::fstream
:既可以用于从文件中读取数据,也可以用于向文件中写入数据的文件流。
下面是这些类的基本用法:
ifstream - 文件读取(输入)
对下列代码:
void test_ifstream() {
std::ifstream file("example.txt"); // 打开名为"example.txt"的文件,并创建一个ifstream对象file
if (file.is_open()) // 检查文件是否成功打开
{
std::string line;
while (std::getline(file, line)) // 逐行读取文件内容,并存储到line变量中
{
std::cout << line << std::endl; // 输出读取的行数据
}
file.close(); // 关闭文件
}
else
{
std::cout << "Failed to open the file." << std::endl;
}
}
在上述代码中,我们通过std::ifstream
创建一个输入文件流对象inputFile
,并打开名为input.txt
的文件。然后,使用std::getline()
函数按行读取文件的内容,并将每一行输出到控制台。最后,使用close()
方法关闭文件。
代码会成功读取example.txt
中的内容并打印:
ofstream - 文件写入(输出)
void test_ofstream()
{
std::ofstream outputFile("output.txt"); // 创建一个名为output.txt的文件
if (outputFile.is_open()) { // 如果文件成功创建
outputFile << "Testing the ofstream function" << std::endl; // 将文本写入文件
outputFile.close(); // 关闭文件
}
else {
std::cout << "无法创建文件 - output.txt" << std::endl;
}
}
在上述代码中,我们通过std::ofstream
创建一个输出文件流对象outputFile
,并创建了名为output.txt
的文件。然后,使用<<运算符将文本写入文件。最后,使用close()
方法关闭文件。
执行代码后,可以发现 output.txt
成功创建并有相应内容:
fstream - 文件读写(输入+输出)
void test_fstream()
{
// 使用std::fstream打开名为"data.txt"的文件,并以输入、输出和追加的方式进行操作。
std::fstream file("data.txt", std::ios::in | std::ios::out | std::ios::app);
if (file) { // 如果文件打开成功
file << "Testing the fstream function" << std::endl; // 写入文本到文件
file.seekg(0); // 将文件指针移到文件开头
std::string line;
while (std::getline(file, line)) { // 读取并输出文件内容
std::cout << line << std::endl;
}
file.close(); // 关闭文件
}
else {
std::cout << "无法打开文件 data.txt" << std::endl;
}
}
根据执行结果,可以看出代码既正确创建了data.txt,由将其读取打印到了控制台:
stringstream
std::stringstream
是C++标准库中的流类,用于在内存中进行字符串的输入输出操作。 它继承自std::basic_stringstream
模板类。
std::stringstream
允许你以流的方式处理字符串数据,可以像处理标准输入输出流一样,使用插入操作符<<将数据插入到流中,或者使用提取操作符>>从流中提取数据。
使用std::stringstream
,你 可以将字符串解析为各种数据类型,也可以将各种数据类型转换为字符串。 例子如下:
#include <sstream>
void test_sstream()
{
std::stringstream ss;
// 插入数据到流中
int num = 114;
ss << "输入数据: " << num;
// 从流中提取数据并输出
std::string result = ss.str();
std::cout << result << std::endl;
// 重新使用流
ss.str(""); // 清空流内容
ss.clear(); // 重置流状态
// 将字符串转换为数据类型
std::string strNum = "514";
int convertedNum;
ss << strNum;
ss >> convertedNum;
std::cout << convertedNum << std::endl;
}
代码执行结果为: