网站首页 > 文章精选 正文
直接操作stdout
代码如下:
#include
int main(){
FILE *old_stdout = stdout;
stdout = fopen("output.log", "w"); // 重定向标准输出
printf("This goes to file"); // 输出到文件
fclose(stdout);
stdout = old_stdout; // 恢复原输出
printf("This goes to terminal\n");
}
代码解析
1.保存原始的 stdout
FILE *old_stdout = stdout;
- stdout 是标准输出流,默认指向终端(控制台)。
- 这里将 stdout 的指针保存到 old_stdout 中,以便后续恢复。
2.重定向 stdout 到文件
stdout = fopen("output.log", "w"); // 重定向标准输出
- 使用 fopen 打开一个文件 output.log,模式为 "w"(写模式,如果文件存在则清空内容,不存在则创建)。
- 将 stdout 指向这个文件。此时,所有通过 printf 等标准输出函数的输出都会被写入 output.log,而不是终端。
3.输出到文件
printf("This goes to file"); // 输出到文件
- 由于 stdout 已经被重定向到 output.log,printf 的输出会写入文件,而不是显示在终端。
4.关闭文件并恢复 stdout
fclose(stdout); // 关闭文件
stdout = old_stdout; // 恢复原输出
- fclose(stdout):关闭文件流,确保所有缓冲数据写入文件。
- stdout = old_stdout:将 stdout 恢复为原始的终端输出流。此时,printf 的输出会重新显示在终端。
代码的潜在问题
- 直接操作 stdout 的风险:
- 直接修改 stdout 可能会导致未定义行为,尤其是在多线程环境中。
- 更安全的方式是使用 freopen,它会自动处理流的重定向和恢复。
- 文件打开失败:
- 如果 fopen 失败(例如文件无法创建),stdout 会被设置为 NULL,导致后续 printf 崩溃。
- 应该检查 fopen 的返回值。
改进版本:使用 freopen
freopen 是专门用于重定向流的函数,更安全且符合标准。以下是改进后的代码:
#include
int main() {
// 保存原始的 stdout
FILE *old_stdout = stdout;
// 重定向 stdout 到文件
if (freopen("output.log", "w", stdout) == NULL) {
perror("Failed to redirect stdout");
return 1;
}
// 输出到文件
printf("This goes to file\n");
// 先关闭当前的 stdout 流
if (fclose(stdout) != 0) {
perror("Failed to close redirected stdout");
return 1;
}
// 恢复 stdout Unix/Linux 系统中,/dev/tty 表示当前终端设备,windows不支持
if (freopen("/dev/tty", "w", stdout) == NULL) {
perror("Failed to restore stdout");
return 1;
}
/*此写法能够支持windows,linux
stdout = old_stdout; // 恢复原来的 stdout
if (fflush(stdout) != 0) { // 确保缓冲区被刷新
perror("Failed to flush stdout");
return 1;
}
*/
// 输出到终端
printf("This goes to terminal\n");
return 0;
}
代码详解
- 使用 freopen 重定向:
- freopen("output.log", "w", stdout):将 stdout 重定向到 output.log。
- 如果重定向失败,freopen 返回 NULL,可以安全处理错误。
- 恢复 stdout:
- 在 Unix/Linux 系统中,/dev/tty 表示当前终端设备。
- 使用 freopen("/dev/tty", "w", stdout) 将 stdout 恢复为终端输出。
- 错误处理:
- 每次调用 freopen 后都检查返回值,确保重定向和恢复操作成功。
输出结果
- 文件 output.log 内容:
This goes to file
- 终端输出:
This goes to terminal
总结
方法 | 优点 | 缺点 |
直接操作 stdout | 简单直观 | 不安全,可能导致未定义行为 |
使用 freopen | 安全、标准、支持错误处理 | 需要额外代码处理恢复逻辑 |
使用 freopen,它是更安全、更标准的重定向方式。
猜你喜欢
- 2025-03-26 PHP常用类 – 缓存类 cache(php几大缓存技术)
- 2025-03-26 C语言strerror函数详解:"错误翻译官"
- 2025-03-26 C语言 ftell 与 fseek 的深度结合应用
- 2025-03-26 C语言putc函数详解:“字符快递员”
- 2025-03-26 C语言srand函数详解:随机数的「播种者」
- 2025-03-26 C语言wctomb函数详解:宽字符到多字节字符的「翻译官」
- 2025-03-26 Linux学习笔记-标准IO库(linux io操作)
- 2025-03-26 小白也能做的物联网(ESP8266)制作遥控船联网远程控制,超详细
- 2025-03-26 C语言remove函数详解:“文件粉碎机”
- 2025-03-26 初学者指南——文件包含(LFI / RFI)
- 最近发表
- 标签列表
-
- newcoder (56)
- 字符串的长度是指 (45)
- drawcontours()参数说明 (60)
- unsignedshortint (59)
- postman并发请求 (47)
- python列表删除 (50)
- 左程云什么水平 (56)
- 计算机网络的拓扑结构是指() (45)
- 稳压管的稳压区是工作在什么区 (45)
- 编程题 (64)
- postgresql默认端口 (66)
- 数据库的概念模型独立于 (48)
- 产生系统死锁的原因可能是由于 (51)
- 数据库中只存放视图的 (62)
- 在vi中退出不保存的命令是 (53)
- 哪个命令可以将普通用户转换成超级用户 (49)
- noscript标签的作用 (48)
- 联合利华网申 (49)
- swagger和postman (46)
- 结构化程序设计主要强调 (53)
- 172.1 (57)
- apipostwebsocket (47)
- 唯品会后台 (61)
- 简历助手 (56)
- offshow (61)