C++IO

本文详细介绍了C++中IO流的核心类,包括std::ostream用于输出,std::istream用于输入,std::iostream集成了两者功能,以及std::istringstream处理字符串流,std::ostringstream用于内存中的字符串格式化,std::ifstream和std::ofstream用于文件读写,std::fstream则是双向操作的文件流。
摘要由CSDN通过智能技术生成

IO

  • C++IO类

在这里插入图片描述

std::ostream


std::ostream 是C++标准库中用于输出数据的流类,它是 std::basic_ostream<char> 的类型别名,主要用于将数据格式化并输出到各种输出设备,最常见的就是标准输出流 std::cout

std::ostream 还可以与其他类集成,只需要重载 operator<< 函数即可,这样便可以将自定义类型的对象方便地输出到流中。例如:

class Point {
public:
    int x, y;
    Point(int x_, int y_) : x(x_), y(y_) {}
    friend std::ostream& operator<<(std::ostream& os, const Point& p) {
        return os << "(" << p.x << ", " << p.y << ")";
    }
};

Point p(3, 4);
std::cout << p; // 输出:(3, 4)

std::istream


std::istream 提供了处理字节或者字符流进行输入操作的功能,主要用于从各种类型的输入流中读取数据,比如从键盘(通过 std::cin)、文件(通过 std::ifstream)或其他用户定义的输入流。

std::istream 还可以通过提取运算符 >> 来实现连续的数据读取,例如:

std::istream& operator>>(std::istream& is, T& value);

这里的 T 可以是内置类型或用户自定义类型,如果类型 T 覆盖了相应的 >> 运算符,则可以从流中正确解析出 T 类型的对象。

#include <iostream>

class Person {
public:
    std::string name;
    int age;

    friend std::istream& operator>>(std::istream& is, Person& p) {
        return is >> p.name >> p.age;
    }
};

int main() {
    Person person;
    std::cin >> person; // 使用自定义的 >> 操作符读取
    std::cout << "Name: " << person.name << ", Age: " << person.age << std::endl;
    return 0;
}

std::iostream


std::iostream 继承自两个重要的类:std::istreamstd::ostream,因此它同时具备了输入和输出的能力。

std::iostream 主要用于处理字节或字符的输入/输出流操作,如从标准输入(通常是键盘,通过 std::cin 实例化)读取数据,并向标准输出(通常是屏幕,通过 std::cout 实例化)写入数据。

由于它继承自 std::istreamstd::ostream,所以可以使用所有这些类提供的方法进行读写操作。例如:

#include <iostream>

int main() {
    int number;
    std::string text;

    std::cout << "Enter a number: ";
    std::cin >> number; // 输入操作

    std::cout << "You entered: " << number << std::endl;

    std::cout << "Now enter some text: ";
    std::getline(std::cin, text); // 输入一行文本

    std::cout << "You entered: " << text << std::endl;

    std::cout << "Writing back the number and text..." << std::endl;
    std::cout << "Number: " << number << ", Text: " << text << std::endl; // 输出操作

    return 0;
}

在这个例子中,我们既使用了 std::cin 从标准输入读取数据(std::cin 是一个 std::istream 的实例),又使用了 std::cout 向标准输出写入数据(std::cout 是一个 std::ostream 的实例)。虽然这里没有直接创建 std::iostream 的对象,但实际上 std::cinstd::cout 都是从 std::iostream 继承而来的。

std::istringstream


这个类是 std::istream 的派生类,专门用于处理存储在字符串中的数据流。

std::istringstream 允许程序员像处理输入流一样处理字符串内容,也就是说,可以使用 >> 运算符或其他 std::istream 的成员函数从字符串中提取和解析数据。

下面是一个使用 std::istringstream 的示例:

#include <sstream>
#include <string>

int main() {
    std::string input = "Hello, World! This is a test message with an integer: 42";
    std::istringstream iss(input);
    std::string greeting;
    std::string message;
    int number;
    // 从字符串流中提取数据
    iss >> greeting >> message;
    std::getline(iss, message, ':'); // 使用 ':' 作为分隔符提取子串
    iss >> number;
    // 输出提取的数据
    std::cout << "Greeting: " << greeting << std::endl;
    std::cout << "Message: " << message << std::endl;
    std::cout << "Integer: " << number << std::endl;
    return 0;
}

在这个示例中,我们创建了一个 std::istringstream 对象 iss,并将其关联到一个包含多个数据项的字符串 input。然后,我们像对待常规输入流一样,从 iss 中提取字符串和整数数据。这样,就可以方便地对字符串进行分割、解析和转换操作。

std::ostringstream

这个类是从 std::ostream 派生出来的,专门用于将数据流格式化并输出到一个内部存储的字符串中。

std::ostringstream 的主要用途是在内存中构建和格式化字符串,而不是立即发送到外部设备(如屏幕或文件)。当你需要多次组合字符串,或者需要动态生成复杂的字符串时,使用 std::ostringstream 就非常方便。

下面是一个使用 std::ostringstream 的示例:

#include <sstream>
#include <string>

int main() {
    int number = 42;
    const char* message = "Hello, World!";
    double floatingPointNumber = 3.14159;

    // 创建一个 ostringstream 对象
    std::ostringstream oss;
    // 将数据插入到 ostringstream 中
    oss << "Number: " << number << ", Message: " << message 
        << ", Floating point number: " << floatingPointNumber;

    // 获取格式化后的字符串
    std::string result = oss.str();
    // 输出结果
    std::cout << "Formatted string: " << result << std::endl;

    return 0;
}

在这个示例中,我们创建了一个 std::ostringstream 对象 oss,然后使用 << 运算符将整数、字符串和浮点数插入到 oss 中。最后,通过调用 str() 函数获取内部存储的格式化字符串,并将其打印出来。

std::stringstream

它同时具备 std::istringstream(从字符串读取)和 std::ostringstream(向字符串写入)的功能,因此可以用来进行双向操作——既能读也能写。

std::stringstream 可以读取和写入字符串,就像处理输入/输出流一样。这意味着你可以将各种类型的数据插入到字符串流中,也可以从该流中提取数据。在处理复杂数据结构转换为字符串或将字符串解析成多种数据类型时特别有用。

以下是 std::stringstream 的基本使用示例:

#include <sstream>
#include <string>

int main() {
    std::string input = "42 Hello";
    std::stringstream ss(input);

    int number;
    std::string word;
    // 从字符串流中读取数据
    ss >> number >> word;  // 现在 number 应为 42,word 应为 "Hello"
    // 验证读取的内容
    std::cout << "Number extracted: " << number << ", Word extracted: " << word << std::endl;

    // 写入新的数据
    ss.clear(); // 清除可能存在的错误标志
    ss.str(""); // 清空当前字符串内容
    ss << "New value: " << 3.14 << ' ';
    // 再次读取并写入
    double newValue;
    ss >> newValue; // newValue 应为 3.14
    ss << "Another word"; // 在现有内容后添加新的字符串
    // 获取最终的字符串内容
    std::string finalString = ss.str();
    std::cout << "Final string: " << finalString << std::endl;
    return 0;
}

在这段代码中,我们首先创建了一个包含 "42 Hello"std::stringstream 对象 ss,然后从中提取了整数和字符串。接着清空并重置了 ss 的内容,向其中写入新的数据,并展示了如何交替进行读取和写入操作。最后,通过调用 str() 函数获取了最终的字符串内容。

std::ifstream


专门用于打开并读取磁盘上的文本或二进制文件。
使用 std::ifstream,你可以像处理标准输入流(如 std::cin)那样,从文件中读取数据。例如,你可以读取整数、浮点数、字符串等各种类型的数据,或者一次性读取整个文件内容。
以下是一个使用 std::ifstream 从文件读取数据的示例:

#include <fstream>
#include <iostream>
#include <string>

int main() {
    std::ifstream inputFile("example.txt"); // 打开名为 "example.txt" 的文件

    if (!inputFile) { // 检查是否成功打开文件
        std::cerr << "Error opening file." << std::endl;
        return 1;
    }

    std::string line;
    while (std::getline(inputFile, line)) { // 逐行读取文件内容
        std::cout << line << std::endl;
    }

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

    return 0;
}

在这个示例中,我们首先创建了一个 std::ifstream 对象 inputFile,并尝试打开文件 “example.txt”。然后检查文件是否成功打开,如果失败则输出错误信息并返回错误码。接着,我们使用 std::getline 函数逐行读取文件内容,并将每一行内容输出到标准输出(屏幕)。最后,确保关闭已打开的文件。

std::ofstream


std::ofstream 是从 std::ostream 派生出来的,专门用于向磁盘上的文件进行文本或二进制数据的写入。

使用 std::ofstream,你可以像处理标准输出流(如 std::cout)那样,将数据写入到文件中。例如,你可以写入整数、浮点数、字符串以及任何可以插入到输出流中的数据。

以下是一个使用 std::ofstream 将数据写入文件的示例:

#include <fstream>
#include <string>

int main() {
    std::ofstream outputFile("output.txt"); // 创建并打开名为 "output.txt" 的文件

    if (!outputFile) { // 检查是否成功打开文件
        std::cerr << "Error opening file." << std::endl;
        return 1;
    }

    std::string message = "Hello, World!";
    outputFile << message << std::endl; // 将字符串写入文件

    int number = 42;
    outputFile << "A sample number: " << number << std::endl; // 写入整数

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

    return 0;
}

在这个示例中,我们首先创建了一个 std::ofstream 对象 outputFile,并尝试打开文件 “output.txt” 以便写入。然后检查文件是否成功打开,如果失败则输出错误信息并返回错误码。接着,我们将一个字符串和一个整数分别写入文件中。最后,确保关闭已打开的文件。当运行这段程序后,将在指定路径下创建或覆盖一个名为 “output.txt” 的文件,并将写入的数据保存到该文件中。

std::fstream


std::fstream 结合了 std::ifstreamstd::ofstream 的功能,既可以读取文件,也可以写入文件,因此它支持对文件进行双向访问。

使用 std::fstream,你可以根据需要打开文件进行读取、写入或同时读写操作。但在实际编程中,为了明确意图和提高代码可读性,通常建议分别使用 std::ifstreamstd::ofstream 对于只读和只写的操作,而在确实需要同时进行读写操作的情况下才使用 std::fstream

以下是一个使用 std::fstream 对文件进行读写操作的示例:

#include <fstream>
#include <string>

int main() {
    std::fstream file("data.txt", std::ios_base::in | std::ios_base::out | std::ios_base::app); // 打开或创建文件,模式为追加和读写

    if (!file) {
        std::cerr << "Error opening file." << std::endl;
        return 1;
    }

    // 读取文件内容
    std::string line;
    if (std::getline(file, line)) {
        std::cout << "Read from file: " << line << std::endl;
    }

    // 写入新数据
    file << "This is a new line written to the file.\n";

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

    return 0;
}

在这个示例中,我们创建了一个 std::fstream 对象 file,并以追加和读写模式打开或创建了 “data.txt” 文件。首先检查文件是否成功打开,然后尝试从文件中读取一行并输出。接着,我们在文件中写入新的一行。最后,确保关闭已打开的文件。

  • 26
    点赞
  • 23
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值