代码仓库shanchuann/CPP-Learninng
标准输入输出流 C++ 标准输入输出流(I/O 流)通过 <iostream> 等头文件封装为面向对象的流对象,是程序与外部设备(键盘、终端、文件)交互的核心机制。相较于 C 语言,C++ 流对象兼具安全性与易用性,支持类型安全的输入输出、灵活的格式控制及动态内存管理。本文聚焦 C++ 标准 I/O 流的核心概念、常用接口及实践示例,帮助开发者快速掌握并正确使用 C++ 标准 I/O 功能。
标准输入流 C++ 标准输入以 std::cin 为核心(istream 类的实例),默认与 C 语言 stdin 同步(可混用 C 风格输入),采用 “行缓冲” 机制 —— 仅当输入换行符 \n 时,键盘输入的字符才会同步到 cin 的内存缓冲区。
核心概念
缓冲区与同步 :cin 有独立内存缓冲区,默认通过 std::cin.sync_with_stdio(true) 与 stdin 同步;取消同步(设为 false)可提升输入效率,但禁止混用 C 风格输入(如 scanf)。
缓冲流程 :键盘输入→硬件缓存→(遇 \n)→cin 内存缓冲区→输入方法读取。
空白字符处理 :默认跳过开头空白字符(空格、Tab、\n),但可通过流控制符调整(如 noskipws 不跳过空白字符)。
常用输入方式 cin >>格式化输入
核心用途 :按变量类型(整数、浮点数、字符串)读取数据,支持链式调用。
关键特点 :默认跳过开头空白字符,遇到空白字符停止读取,残留 \n 在缓冲区;类型安全(无需手动指定格式符)。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 #include <iostream> using namespace std;int main () { cout << "Please input two integer and a string(cin): " ; int a, b; cin >> a >> b; cout << "a = " << a << ", b = " << b << endl; cout << "Please input a string: " ; char str[20 ]; cin >> str; cout << "str = " << str << endl; getchar (); cout << "Please input a character(no skip white space): " ; char c, d; cin >> noskipws >> c; cout << "c = " << c << endl; cout << "Please input a character: " ; cin >> skipws >> d; cout << "d = " << d << endl; return 0 ; }
注意事项 :cin >> 无法读取含空格的完整字符串;若输入类型不匹配(如输入字母给整数),cin 会进入 fail 状态,需用 cin.clear() 恢复并清理缓冲区。
cin.get()单字符 / 指定长度读取
核心用途 :读取单个字符或指定长度的字符串,支持保留空白字符,提供三种重载形式。
关键特点 :不跳过空白字符;读取指定长度时丢弃终止符(默认 \n),不残留缓冲区;输入超长度时,剩余字符残留缓冲区(cin 状态正常)。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 #include <iostream> using namespace std;int main () { getchar (); cout << "Please input a character(cin.get()): " ; char e; e = cin.get (); cout << "e = " << e << endl; getchar (); cout << "Please input a character(cin.get()): " ; char f; cin.get (f); cout << "f = " << f << endl; getchar (); cout << "Please input a string(cin.get()): " ; char str1[20 ]; cin.get (str1, sizeof (str1), '\n' ); cout << "str1 = " << str1 << endl; getchar (); return 0 ; }
cin.get() 读取字符串时,若输入长度超过 n-1(n 为缓冲区大小),剩余字符会残留缓冲区,等待下次读取。
cin.getline()指定长度行读取(字符数组)
核心用途 :读取一整行字符串(含空格)到字符数组,自动处理终止符(默认 \n)。
关键特点 :丢弃终止符 \n(不残留缓冲区);若输入长度超过 n-1,cin 会进入 fail 状态(需手动恢复),与 cin.get(char* buf, int n)差异显著。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 #include <iostream> using namespace std;int main () { cout << "Please input a string(cin.getline()): " ; char str2[20 ]; cin.getline (str2, sizeof (str2)); cout << "str2 = " << str2 << endl; const int n = 10 ; char str[n]; cout << "Please input a string(cin >> 后接 cin.getline()): " ; cin >> str; cout << str << endl; getchar (); cout << "Please input a string(cin.getline()): " ; cin.getline (str, sizeof (str)); cout << str << endl; return 0 ; }
std::getline()动态字符串行读取
核心用途 :读取一整行字符串(含空格)到 std::string 对象,需包含<string>头文件,支持动态内存分配(无溢出风险)。
关键特点 :丢弃终止符 \n(不残留缓冲区);一次性读完缓冲区数据,无长度限制;与 cin >> 混用时需清理残留 \n。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 #include <iostream> #include <string> using namespace std;int main () { getchar (); cout << "Please input a string(getline()): " ; string str3; getline (cin, str3); cout << "str3 = " << str3 << endl; cout << "Please input a string(after residual '\\n'): " ; getchar (); getline (cin, str3); cout << "str3 = " << str3 << endl; return 0 ; }
若 cin >> 后直接调用 std::getline(),cin >> 残留的 \n 会被std::getline()读取为空白行,需用getchar()或 cin.ignore() 清理缓冲区。
标准输出流 C++ 标准输出通过<iostream>提供三个核心流对象:std::cout(正常输出)、std::cerr(错误输出)、std::clog(日志输出),均为 ostream 类实例,缓冲特性与用途差异显著。
核心流对象对比
流对象
缓冲特性
核心用途
输出时机
cout
行缓冲
正常程序结果输出(如计算结果)
遇 \n、endl 或 fflush 时
cerr
无缓冲
错误信息输出(如文件打开失败)
数据写入后立即输出
clog
行缓冲
日志信息输出(如调试日志)
遇 \n 或 fflush 时
常用输出方式 cout <<:格式化输出
核心用途 :按变量类型输出数据,支持链式调用与精细格式控制(需 <iomanip> 头文件)。
关键特点 :默认行缓冲,endl 等价于 “换行 + 强制刷新缓冲区”(效率低于 \n);支持通过 fixed、setprecision 等控制浮点数格式。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 #include <iostream> #include <iomanip> using namespace std;int main () { int a = 123 ; float b = 3.14159 ; char s[] = "Hello, C plusplus!" ; cout << "Number a = " << a << endl; cout << "Number b = " << fixed << setprecision (2 ) << b << endl; cout << "String s = " << s << endl; cout << "Hello, C plusplus!" << endl; int i = 10 ; while (i > 0 ) { cout << "i = " << i << endl; i--; } cout << "END" << endl; return 0 ; }
cerr:错误信息输出
核心用途 :输出程序运行中的错误信息(如文件打开失败、参数非法),无缓冲特性确保错误信息优先显示(即使程序崩溃)。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 #include <iostream> using namespace std;int main () { char errorMsg[] = "File open FAILED!" ; cerr << "[Error] " << errorMsg << endl; int i = 3 ; while (i > 0 ) { i--; } return 0 ; }
clog:日志信息输出
核心用途 :输出程序运行日志(如调试信息、状态记录),行缓冲特性减少 I/O 开销(适合批量输出)。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 #include <iostream> using namespace std;int main () { clog << "Log: Program started." << endl; clog << "Log: Reading configuration..." << endl; clog << "Log: Configuration loaded successfully." << endl; for (int i = 0 ; i < 2 ; i++) { clog << "Log: Processing task " << i + 1 << endl; } clog << "Log: Program ended." << endl; return 0 ; }
C++ 字符串输入 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 #include <iostream> #include <string> using namespace std;int main () { const int n = 10 ; char charStr[n]; string str; cout << "1. Please input a string(no space, cin >>): " ; cin >> charStr; cout << "Result: " << charStr << endl; getchar (); cout << "2. Please input a string(with space, cin.getline()): " ; cin.getline (charStr, sizeof (charStr)); cout << "Result: " << charStr << endl; cout << "3. Please input a string(ends with '@', cin.get()): " ; cin.get (charStr, n, '@' ); cout << "Result: " << charStr << endl; getchar (); cout << "4. Please input a string(dynamic, std::getline()): " ; getline (cin, str); cout << "Result: " << str << endl; return 0 ; }
其他 const编译策略 在C++中,定义const int a = 10后,经过一系列指针操作,在监视器中得到的结果如下图所示
但输出却是
1 a = 10, *p = 100, b = 10
这是因为C++会将我们定义的常变量在编译阶段替换为他们的值如下
1 2 3 4 5 6 7 const int a = 10 ;int * p = (int *)&a;int b = 0 ;*p = 100 ; b = 10 ; printf ("a = %d, *p = %d, b = %d\n" , 10 ,*p, b);return 0 ;
虽然a的值可以替换为100,但在编译阶段已经被替换
当我们将文件后缀替换为.c后,得到输出如下
1 a = 100, *p = 100, b = 100
预定义宏 C++ 编译器内置一组预定义宏 ,可通过 cout 直接输出,用于获取源文件信息、编译时间、代码位置及 C++ 标准版本,是调试定位与版本管理的实用工具。
代码行
预定义宏
功能说明
cout << __FILE__ << endl;
__FILE__
输出当前源文件的完整路径或文件名(如 D:\code\test.cpp,取决于编译器)
cout << __DATE__ << endl;
__DATE__
输出代码的编译日期(格式:Mmm dd yyyy,如 Oct 16 2025)
cout << __TIME__ << endl;
__TIME__
输出代码的编译时间(非运行时间,格式:hh:mm:ss,如 09:45:30)
cout << __LINE__ << endl;
__LINE__
输出当前 LINE 所在的代码行号(如代码中该宏在第 6 行,则输出 6)
cout <<__func__<< endl;
__func__
输出当前所在函数的名称(此处为 main,C++11 及以后标准支持)
cout << __cplusplus << endl;
__cplusplus
输出编译器支持的 C++ 标准版本号(如 201703L 对应 C++17,202002L 对应 C++20)
1 2 3 4 5 6 7 8 int main () { cout << __FILE__ << endl; cout << __DATE__ << endl; cout << __TIME__ << endl; cout << __LINE__ << endl; cout << __func__ << endl; cout << __cplusplus << endl; }
输出
1 2 3 4 5 6 D:\Code\C++code\CPP-Learninng\io.cpp Oct 14 2025 15:52:28 411 main 199711