当前位置: 首页 > news >正文

c++输入输出详解

C++ 的输入输出(I/O)主要通过标准库中的流对象实现,核心是对“数据流”的操作。其语法规则围绕“流对象”“操作符”和“数据类型匹配”展开,以下从标准 I/O(控制台)文件 I/O 两部分详细说明。

一、标准输入输出(控制台 I/O)

标准 I/O 用于程序与用户通过键盘/屏幕交互,核心依赖 <iostream> 头文件中的三个流对象:

  • cout:标准输出流(对应屏幕)
  • cin:标准输入流(对应键盘)
  • cerr/clog:标准错误流(用于输出错误信息,cerr 不缓冲,clog 缓冲)

1. 输出操作(cout

基本语法

通过 <<(输出流操作符)cout 流中“插入”数据,格式:

cout << 数据1 << 数据2 << ... << 操纵符;
  • 数据:可以是常量、变量、表达式(支持基本类型:int/double/string 等)。
  • 操纵符:用于控制输出格式(如换行、刷新缓冲区等)。

示例与规则

#include <iostream>  // 必须包含的头文件
#include <string>    // 使用 string 类型需包含using namespace std;  // 简化代码,否则需写 std::coutint main() {// 1. 输出常量cout << "Hello World";  // 输出字符串常量cout << 123;            // 输出整数常量cout << 3.14;           // 输出浮点数常量// 2. 输出变量int age = 20;string name = "Alice";cout << name << " is " << age << " years old";  // 链式输出变量和常量// 3. 控制输出格式(常用操纵符)cout << endl;           // 换行 + 刷新缓冲区(等价于 "\n" + 刷新)cout << "Line 1\nLine 2";  // \n 仅换行,不刷新cout << flush;          // 强制刷新缓冲区(不换行)return 0;
}

核心规则

  • 链式输出<< 操作符返回流对象本身(cout),因此可连续拼接多个输出项。
  • 自动类型转换cout 会根据数据类型自动转为字符串输出(无需手动转换,如直接输出 int/double)。
  • 操纵符作用
    • endl:换行 + 刷新缓冲区(确保数据立即显示)。
    • \n:仅换行(效率更高,适合大量输出)。
    • flush:仅刷新缓冲区(无换行)。

2. 输入操作(cin

基本语法

通过 >>(输入流操作符)cin 流中“提取”数据到变量,格式:

cin >> 变量1 >> 变量2 >> ...;
  • 变量:必须是已声明的变量(需指定类型,如 int/string 等)。

示例与规则

#include <iostream>
#include <string>using namespace std;int main() {// 1. 输入单个变量int num;cout << "请输入一个整数:";cin >> num;  // 从键盘读取整数到 num// 2. 连续输入多个变量(空格/换行分隔)string name;int age;cout << "请输入姓名和年龄:";cin >> name >> age;  // 输入 "Alice 20" → name="Alice", age=20// 3. 处理输入失败(如输入类型不匹配)if (cin.fail()) {  // 输入失败(如预期 int 却输入字符串)cout << "输入格式错误!" << endl;cin.clear();   // 清除错误状态// 忽略缓冲区中剩余的错误数据cin.ignore(numeric_limits<streamsize>::max(), '\n');}return 0;
}

核心规则

  • 分隔符cin空白字符(空格、Tab、换行)作为输入项的分隔符,自动跳过空白。
  • 类型匹配:输入的数据类型必须与变量类型一致,否则会触发输入失败(需用 cin.fail() 检测)。
  • 缓冲区机制:输入数据先存到缓冲区,>> 从缓冲区提取数据,若缓冲区为空则等待用户输入。
  • 读取字符串限制cin >> string 只能读取到第一个空白字符(如需读取整行,需用 getline)。

3. 读取整行输入(getline

当需要读取包含空格的完整行(如句子)时,使用 getline 函数:

#include <iostream>
#include <string>using namespace std;int main() {string line;cout << "请输入一行文字:";getline(cin, line);  // 读取整行(包括空格)到 linecout << "你输入的是:" << line << endl;return 0;
}

注意事项

  • getline 会读取换行符 \n 之前的所有字符,并自动丢弃换行符(不存入变量)。
  • 若之前用 cin >> 读取过数据,缓冲区可能残留换行符,导致 getline 直接读取空行,需先清除:
    int num;
    cin >> num;
    cin.ignore();  // 忽略缓冲区中残留的换行符
    string line;
    getline(cin, line);  // 正常读取一行
    

二、文件输入输出(文件 I/O)

文件 I/O 用于读写磁盘文件,核心依赖 <fstream> 头文件中的三个流类:

  • ifstream:输入文件流(读文件)
  • ofstream:输出文件流(写文件)
  • fstream:可同时读写的文件流

1. 打开文件的方式

通过流对象的 open 方法或构造函数打开文件,需指定文件路径打开模式

#include <fstream>
#include <iostream>using namespace std;int main() {// 方式1:通过构造函数打开ofstream outFile("output.txt", ios::out);  // 输出模式(默认,覆盖写入)// 方式2:通过 open 方法打开ifstream inFile;inFile.open("input.txt", ios::in);  // 输入模式(默认,只读)// 检查文件是否打开成功if (!inFile.is_open()) {cerr << "文件打开失败!" << endl;return 1;}// 操作文件...// 关闭文件(析构函数会自动关闭,但手动关闭更规范)inFile.close();outFile.close();return 0;
}

常用打开模式

模式 含义 适用流
ios::in 只读方式打开(默认 for ifstream) ifstream
ios::out 只写方式打开(默认 for ofstream),覆盖原有内容 ofstream
ios::app 追加模式(在文件末尾写入) ofstream
ios::binary 二进制模式(默认是文本模式) 所有文件流
ios::trunc 若文件存在则清空(与 ios::out 结合) ofstream
ios::ate 打开后定位到文件末尾 fstream

模式可组合使用(用 | 连接),例如 ios::out | ios::binary 表示二进制写模式。

2. 读文件(ifstream

基本用法

cin 类似,通过 >>getline 读取文件内容:

#include <fstream>
#include <iostream>
#include <string>using namespace std;int main() {ifstream inFile("input.txt");if (!inFile) {  // 等价于 !inFile.is_open()cerr << "文件打开失败!" << endl;return 1;}// 方法1:用 >> 读取(以空白分隔)int num;inFile >> num;  // 从文件读整数// 方法2:用 getline 读取整行string line;while (getline(inFile, line)) {  // 循环读每行,直到文件结束cout << line << endl;}// 检查是否到文件末尾(而非错误)if (inFile.eof()) {cout << "文件读取完毕" << endl;}inFile.close();return 0;
}

3. 写文件(ofstream

基本用法

cout 类似,通过 << 写入数据到文件:

#include <fstream>
#include <string>using namespace std;int main() {// 覆盖写入(默认 ios::out)ofstream outFile("output.txt");// 追加写入:ofstream outFile("output.txt", ios::app);if (!outFile) {cerr << "文件打开失败!" << endl;return 1;}// 写入数据outFile << "Hello File" << endl;  // 写入字符串+换行int age = 20;outFile << "Age: " << age << endl;  // 写入变量outFile.close();return 0;
}

三、输入输出的格式控制

C++ 提供了多种方式控制 I/O 格式(如对齐、精度、进制等),常用两种方式:

1. 操纵符(iomanip 头文件)

通过操纵符直接在流中设置格式:

#include <iostream>
#include <iomanip>  // 需包含此头文件using namespace std;int main() {double pi = 3.1415926535;// 控制浮点数精度(保留 2 位小数)cout << fixed << setprecision(2) << pi << endl;  // 输出:3.14// 控制整数进制(十进制、八进制、十六进制)int num = 255;cout << dec << num << endl;  // 十进制(默认):255cout << oct << num << endl;  // 八进制:377cout << hex << num << endl;  // 十六进制:ff// 控制宽度和对齐(右对齐,宽度 10)cout << setw(10) << "Name" << setw(5) << "Age" << endl;cout << setw(10) << "Alice" << setw(5) << 20 << endl;return 0;
}

常用操纵符:

  • fixed + setprecision(n):控制浮点数小数位数(n 位)。
  • setw(n):设置输出宽度(仅对下一个输出项有效)。
  • left/right:左对齐/右对齐(配合 setw 使用)。
  • dec/oct/hex:设置整数为十进制/八进制/十六进制。

2. 成员函数(流对象的方法)

通过流对象的成员函数设置格式(更灵活,可重复使用):

#include <iostream>using namespace std;int main() {double pi = 3.1415926535;// 设置精度(等价于 fixed + setprecision(2))cout.precision(2);cout << fixed;cout << pi << endl;  // 输出:3.14// 设置宽度和对齐cout.width(10);       // 宽度 10cout << left;         // 左对齐cout << "Alice" << endl;  // 输出:Alice     // (Alice 后补 5 个空格,凑满 10 宽度)return 0;
}

四、核心规则总结

  1. 流对象是核心:所有 I/O 操作围绕 cout/cin(控制台)或 ifstream/ofstream(文件)展开。
  2. 操作符含义<< 用于输出(插入到流),>> 用于输入(从流提取),支持链式操作。
  3. 类型必须匹配:输入时,变量类型需与输入数据类型一致,否则会触发错误。
  4. 缓冲区机制:I/O 数据先存于缓冲区,endlflush 可强制刷新(立即显示/写入)。
  5. 文件操作步骤:打开文件 → 检查是否成功 → 读写数据 → 关闭文件(或依赖析构自动关闭)。

掌握这些规则后,就能灵活处理 C++ 中的各种输入输出场景,包括控制台交互和文件读写。

http://www.hskmm.com/?act=detail&tid=16706

相关文章:

  • docker/docker compose/k8s
  • 中国开发者迎来新选择:Gitee成为研发协作平台转型期的中流砥柱
  • RK3588-ubuntu server - 详解
  • 一文教你上手 Geometric Glovius 6.0:安装、授权与首个项目演示
  • 32单片机+free rtos移植CJSON库函数主要流程
  • Gitee如何重塑中国开发者生态:本土化创新与数字化转型的双重奏
  • 输入输出接口
  • Go语言中的信号捕获与优雅退出:SIGINT、SIGTERM和SIGKILL详解 - 若
  • (二)3.1.9 生产“稳”担当:Apache DolphinScheduler Worker 服务源码全方位解析
  • 完整教程:生产环境实战:Spring Cloud Sleuth与Zipkin分布式链路追踪实践
  • 训练“系统级思维”,听时序数据库 IoTDB Committer 说说从设计到应用的成长
  • 关于gradle项目启动
  • Day08
  • 常见闪存区别
  • 进程、线程、协程、虚拟线程,傻傻分不清楚
  • 事倍功半是蠢蛋55 ctrl+shift+f 每次搜索都按倒繁体
  • Ini文件的读写
  • 数据跨境传输解决方案助力企业安全合规高效流通
  • 题解:P9454 [ZSHOI-R1] 巡城
  • QuestaSim奔溃后再次打开无法仿真
  • 软考架构备考-软件可靠性、知识产权和标准化
  • 医院内外网文件传输:平衡安全与效率的关键链路!
  • 我的第一个赚钱网站 -- 从网站源码到集成AdSense获利的全过程
  • Gradle读取仓库配置文件的优先级
  • opencv学习记录5
  • PCS PMA,如何理解硬核IP
  • pycharm中使用调试模式运行 uvicorn.run(app)报错TypeError: _patch_asyncio.locals.run() got an unexpected keywor解决
  • 交换机命令
  • 2025.9.25
  • 易基因:Cell Rep:华农任文凯团队利用ChIP-seq及多组学解析过敏性疾病的关键调控机制|项目文章