iostream处理控制台IO详细解析

文章目录

      • 关键概念
      • 预定义对象
      • 输入操作
      • 输出操作
      • 输入验证
      • 高级特性
        • 1. 流的状态标志
        • 2. 自定义流操作符
        • 3. 文件流
        • 4. 格式化输出
      • 案例 1:输入验证
      • 案例 2:自定义流操作符
      • 案例 3:文件流
      • 案例 4:格式化输出
      • 案例 5:综合应用

iostream 是 C++ 中非常重要的一个库,它提供了强大的工具来处理控制台输入输出(I/O)。下面是对 iostream 库中关键概念和功能的详细解析。

关键概念

  1. iostream 库

    • iostream 是 C++ 标准库的一部分,主要用于处理输入和输出操作。
    • 它包含了一些重要的类,如 istreamostreamiostream,以及一些预定义的对象,如 cincoutcerrclog
  2. istream 类

    • istream 类用于处理输入操作。
    • 预定义对象 cinistream 的实例,通常用于从标准输入(通常是键盘)读取数据。
  3. ostream 类

    • ostream 类用于处理输出操作。
    • 预定义对象 coutostream 的实例,通常用于向标准输出(通常是屏幕)写入数据。
    • 其他预定义对象包括 cerrclog,它们也都是 ostream 的实例,但用于错误输出。
  4. iostream 类

    • iostream 类继承自 istreamostream,因此它可以同时处理输入和输出。
    • 虽然 iostream 类本身不常用,但它是 fstream(用于文件 I/O)的基础。

预定义对象

  1. cin

    • cin 是一个全局对象,类型为 std::istream
    • 它用于从标准输入读取数据。
    • 示例:
      int number;
      cin >> number; // 从标准输入读取一个整数
      
  2. cout

    • cout 是一个全局对象,类型为 std::ostream
    • 它用于向标准输出写入数据。
    • 示例:
      int number = 42;
      cout << "The number is: " << number << endl; // 向标准输出写入数据
      
  3. cerr

    • cerr 是一个全局对象,类型为 std::ostream
    • 它用于输出错误信息,通常不会被缓冲,这意味着错误信息会立即显示在屏幕上。
    • 示例:
      cerr << "An error occurred!" << endl; // 输出错误信息
      
  4. clog

    • clog 是一个全局对象,类型为 std::ostream
    • 它也用于输出错误或调试信息,但与 cerr 不同的是,它会被缓冲。
    • 示例:
      clog << "This is a debug message." << endl; // 输出调试信息
      

输入操作

  1. 提取运算符 (>>)

    • >> 运算符用于从输入流中提取数据,并将其存储到变量中。
    • 示例:
      int a, b;
      cin >> a >> b; // 从标准输入读取两个整数
      
  2. getline 函数

    • getline 函数用于从输入流中读取一行文本,包括空格。
    • 示例:
      string line;
      getline(cin, line); // 从标准输入读取一行文本
      

输出操作

  1. 插入运算符 (<<)

    • << 运算符用于将数据插入到输出流中。
    • 示例:
      int a = 10, b = 20;
      cout << "a = " << a << ", b = " << b << endl; // 向标准输出写入数据
      
  2. 操纵符

    • 操纵符用于修改输出格式,例如设置宽度、精度等。
    • 常见的操纵符包括 setwsetprecisionfixed 等。
    • 示例:
      #include 
      #include 
      using namespace std;
      
      int main() {
          double pi = 3.1415926535;
          cout << "Default output: " << pi << endl;
          cout << "Fixed with 2 decimal places: " << fixed << setprecision(2) << pi << endl;
          cout << "Width of 10: " << setw(10) << pi << endl;
          return 0;
      }
      

输入验证

  1. 检查流状态
    • 可以使用 cin 的成员函数来检查输入是否成功。
    • 常用的成员函数包括 eof()fail()bad()good()
    • 示例:
      int number;
      cout << "Enter an integer: ";
      cin >> number;
      
      if (cin.fail()) {
          cin.clear(); // 清除错误标志
          cin.ignore(std::numeric_limits<std::streamsize>::max(), '\n'); // 忽略输入缓冲区中的剩余字符
          cout << "Invalid input! Please enter an integer." << endl;
      } else {
          cout << "You entered: " << number << endl;
      }
      

小结

  • iostream 库提供了丰富的工具来处理控制台输入输出。
  • 使用 cincout 可以方便地进行输入和输出操作。
  • 操纵符和流状态检查可以帮助你更好地控制输入输出格式和错误处理。

接下来我们继续深入探讨 iostream 库中的一些高级特性和用法。

高级特性

1. 流的状态标志

iostream 库提供了几种状态标志,用于检查输入输出操作是否成功。这些状态标志可以通过 cincout 的成员函数来访问。

  • eof():检查是否到达文件末尾。
  • fail():检查是否发生输入失败(例如,输入类型不匹配)。
  • bad():检查是否发生严重错误(例如,文件损坏)。
  • good():检查是否一切正常。

示例:

#include 
using namespace std;

int main() {
    int number;
    cout << "Enter an integer: ";
    cin >> number;

    if (cin.fail()) {
        cin.clear(); // 清除错误标志
        cin.ignore(numeric_limits<streamsize>::max(), '\n'); // 忽略输入缓冲区中的剩余字符
        cout << "Invalid input! Please enter an integer." << endl;
    } else {
        cout << "You entered: " << number << endl;
    }

    return 0;
}
2. 自定义流操作符

你可以通过重载 <<>> 运算符来自定义流操作,以便处理自定义类型的输入输出。

示例:

#include 
#include 
using namespace std;

class Person {
public:
    string name;
    int age;

    // 重载 << 运算符
    friend ostream& operator<<(ostream& os, const Person& p) {
        os << "Name: " << p.name << ", Age: " << p.age;
        return os;
    }

    // 重载 >> 运算符
    friend istream& operator>>(istream& is, Person& p) {
        cout << "Enter name: ";
        is >> p.name;
        cout << "Enter age: ";
        is >> p.age;
        return is;
    }
};

int main() {
    Person p;
    cout << "Enter person details: " << endl;
    cin >> p; // 使用自定义的 >> 运算符
    cout << "Person details: " << p << endl; // 使用自定义的 << 运算符

    return 0;
}
3. 文件流

虽然这里主要讨论控制台 I/O,但 iostream 库也支持文件 I/O。文件流类 ifstreamofstream 分别用于文件输入和输出,而 fstream 可以同时处理输入和输出。

示例:

#include 
#include 
using namespace std;

int main() {
    ofstream outFile("example.txt");
    if (!outFile.is_open()) {
        cerr << "Failed to open file for writing." << endl;
        return 1;
    }

    outFile << "Hello, World!" << endl;
    outFile.close();

    ifstream inFile("example.txt");
    if (!inFile.is_open()) {
        cerr << "Failed to open file for reading." << endl;
        return 1;
    }

    string line;
    while (getline(inFile, line)) {
        cout << line << endl;
    }
    inFile.close();

    return 0;
}
4. 格式化输出

除了常用的 setwsetprecisionfixed 操纵符外,iostream 库还提供了其他一些格式化工具。

  • setfill:设置填充字符。
  • leftrightinternal:设置对齐方式。
  • boolalpha:以字母形式输出布尔值。

示例:

#include 
#include 
using namespace std;

int main() {
    double pi = 3.1415926535;
    int number = 42;

    // 设置宽度和填充字符
    cout << setw(10) << setfill('*') << number << endl;

    // 设置对齐方式
    cout << setw(10) << left << number << endl;
    cout << setw(10) << right << number << endl;
    cout << setw(10) << internal << number << endl;

    // 以字母形式输出布尔值
    bool flag = true;
    cout << boolalpha << flag << endl;

    return 0;
}

小结

  • 状态标志:用于检查流的状态,确保输入输出操作的成功。
  • 自定义流操作符:通过重载 <<>> 运算符,可以处理自定义类型的输入输出。
  • 文件流:使用 ifstreamofstreamfstream 类处理文件输入输出。
  • 格式化输出:使用各种操纵符来控制输出格式。

下面是一些详细具体的案例,涵盖了 iostream 库的多个方面,包括输入验证、自定义流操作符、文件流和格式化输出。

案例 1:输入验证

在这个案例中,我们将实现一个程序,要求用户输入一个有效的整数,并在输入无效时给出提示。

#include 
#include 
using namespace std;

int main() {
    int number;
    cout << "请输入一个整数: ";

    while (!(cin >> number)) { // 检查输入是否失败
        cin.clear(); // 清除错误标志
        cin.ignore(numeric_limits<streamsize>::max(), '\n'); // 忽略输入缓冲区中的剩余字符
        cout << "无效输入!请再次输入一个整数: ";
    }

    cout << "你输入的整数是: " << number << endl;

    return 0;
}

案例 2:自定义流操作符

在这个案例中,我们将创建一个 Person 类,并重载 <<>> 运算符,以便能够方便地输入和输出 Person 对象。

#include 
#include 
using namespace std;

class Person {
public:
    string name;
    int age;

    // 重载 << 运算符
    friend ostream& operator<<(ostream& os, const Person& p) {
        os << "姓名: " << p.name << ", 年龄: " << p.age;
        return os;
    }

    // 重载 >> 运算符
    friend istream& operator>>(istream& is, Person& p) {
        cout << "请输入姓名: ";
        is >> p.name;
        cout << "请输入年龄: ";
        is >> p.age;
        return is;
    }
};

int main() {
    Person p;
    cout << "请输入个人信息: " << endl;
    cin >> p; // 使用自定义的 >> 运算符
    cout << "个人信息: " << p << endl; // 使用自定义的 << 运算符

    return 0;
}

案例 3:文件流

在这个案例中,我们将创建一个程序,读取一个文件的内容并将其输出到控制台。

#include 
#include 
using namespace std;

int main() {
    // 写入文件
    ofstream outFile("example.txt");
    if (!outFile.is_open()) {
        cerr << "无法打开文件以写入." << endl;
        return 1;
    }

    outFile << "你好,世界!" << endl;
    outFile << "这是第二行." << endl;
    outFile.close();

    // 读取文件
    ifstream inFile("example.txt");
    if (!inFile.is_open()) {
        cerr << "无法打开文件以读取." << endl;
        return 1;
    }

    string line;
    while (getline(inFile, line)) {
        cout << line << endl;
    }
    inFile.close();

    return 0;
}

案例 4:格式化输出

在这个案例中,我们将使用各种操纵符来格式化输出,包括设置宽度、精度和对齐方式。

#include 
#include 
using namespace std;

int main() {
    double pi = 3.1415926535;
    int number = 42;

    // 设置宽度和填充字符
    cout << "宽度为10,填充字符为'*': " << setw(10) << setfill('*') << number << endl;

    // 设置对齐方式
    cout << "左对齐: " << setw(10) << left << number << endl;
    cout << "右对齐: " << setw(10) << right << number << endl;
    cout << "内部对齐: " << setw(10) << internal << number << endl;

    // 设置小数点后两位输出
    cout << "固定格式,小数点后两位: " << fixed << setprecision(2) << pi << endl;

    // 以字母形式输出布尔值
    bool flag = true;
    cout << "布尔值: " << boolalpha << flag << endl;

    return 0;
}

案例 5:综合应用

在这个案例中,我们将结合上述所有功能,创建一个简单的地址簿程序,允许用户输入联系人信息并将其保存到文件中。

#include 
#include 
#include 
#include 
using namespace std;

class Contact {
public:
    string name;
    string phone;
    string email;

    // 重载 << 运算符
    friend ostream& operator<<(ostream& os, const Contact& c) {
        os << "姓名: " << c.name << ", 电话: " << c.phone << ", 邮箱: " << c.email;
        return os;
    }

    // 重载 >> 运算符
    friend istream& operator>>(istream& is, Contact& c) {
        cout << "请输入姓名: ";
        is >> c.name;
        cout << "请输入电话: ";
        is >> c.phone;
        cout << "请输入邮箱: ";
        is >> c.email;
        return is;
    }
};

void saveContactsToFile(const vector<Contact>& contacts, const string& filename) {
    ofstream outFile(filename);
    if (!outFile.is_open()) {
        cerr << "无法打开文件以写入." << endl;
        return;
    }

    for (const auto& contact : contacts) {
        outFile << contact.name << ' ' << contact.phone << ' ' << contact.email << endl;
    }
    outFile.close();
}

vector<Contact> loadContactsFromFile(const string& filename) {
    vector<Contact> contacts;
    ifstream inFile(filename);
    if (!inFile.is_open()) {
        cerr << "无法打开文件以读取." << endl;
        return contacts;
    }

    string name, phone, email;
    while (inFile >> name >> phone >> email) {
        contacts.push_back({name, phone, email});
    }
    inFile.close();
    return contacts;
}

int main() {
    vector<Contact> contacts;
    int choice;

    do {
        cout << "地址簿菜单:\n";
        cout << "1. 添加联系人\n";
        cout << "2. 查看联系人\n";
        cout << "3. 保存联系人到文件\n";
        cout << "4. 加载联系人从文件\n";
        cout << "0. 退出\n";
        cout << "请选择: ";
        cin >> choice;

        switch (choice) {
            case 1: {
                Contact contact;
                cin >> contact;
                contacts.push_back(contact);
                break;
            }
            case 2: {
                if (contacts.empty()) {
                    cout << "没有联系人记录." << endl;
                } else {
                    for (const auto& contact : contacts) {
                        cout << contact << endl;
                    }
                }
                break;
            }
            case 3: {
                saveContactsToFile(contacts, "contacts.txt");
                cout << "联系人已保存到文件." << endl;
                break;
            }
            case 4: {
                contacts = loadContactsFromFile("contacts.txt");
                cout << "联系人已从文件加载." << endl;
                break;
            }
            case 0:
                cout << "退出程序." << endl;
                break;
            default:
                cout << "无效选择,请重新输入." << endl;
        }
    } while (choice != 0);

    return 0;
}

这些案例展示了 iostream 库在实际编程中的应用,包括输入验证、自定义流操作符、文件流和格式化输出。希望这些示例能帮助你更好地理解和使用 iostream 库。

海量H5小游戏、微信小游戏、Web casualgame源码
试玩地址: https://www.bojiogame.sg
看上哪一款,需要源码的csdn私信我

————————————————

​最后我们放松一下眼睛
在这里插入图片描述

你可能感兴趣的:(c++,算法,开发语言,iostream)