博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
printf重定向
阅读量:6979 次
发布时间:2019-06-27

本文共 1776 字,大约阅读时间需要 5 分钟。

用到第三方库使用printf打印调试信息的时候往往需要重定向日志到文件, 但如果没有源码或修改点较多时就比较麻烦. 这里提供两个重定位方法:

1. 修改值为1的文件描述符
默认printf打印指向标准输出stdout(fd=1), 最终指向终端. 因此可以关闭值为1的文件描述符再打开另一文件, 之后printf打印就被写入该文件中. 注意这种方法必须保证关闭fd与打开文件之间不会有其它文件操作(内核分配fd是顺序分配的, 如有第三个文件打开则第三个文件的fd被设为1), 且fork进程会保留对应的fd, 即新进程也会操作同一文件, 需要做好互斥(可以通过关闭子进程fd来解决这个问题).
2. 修改printf实现
定义同名同类型的printf并修改其实现. 这里要注意一点, 默认打印不带参数的字符串时gcc会将printf优化为puts, 解决办法有两个: 一是同样重定义puts, 二是编译时添加-fno-builtin-printf.

1 #include 
2 #include
3 #include
4 #include
5 #include
6 #define REDIRECT 7 #undef REDIRECT 8 #ifdef REDIRECT 9 int fd = -1;10 #else11 FILE *fp = NULL;12 int printf(const char *fmt, ...)13 {14     va_list args;15     int ret = 0;16     va_start(args, fmt);17     ret = vfprintf(fp, fmt, args);18     va_end(args);19     fflush(fp);20     return ret;21 }22 /*23 int puts(const char *s)24 {25     //add \n here to avoid buffering26     return printf("%s\n", s);27 }28 */29 #endif30 int main()31 {32 #ifdef REDIRECT33     close(1);34     35     fd = open("./out", O_RDWR | O_CREAT, 0755);36     if (1 != fd)37     {38         fprintf(stderr, "open file fail with %d\n", fd);39         return -1;40     }41     printf("this line shall written into file!\n");42     //flush cache, man stdout for detail43     fsync(fd);44 #else45     fp = fopen("./out", "w+");46     if (NULL == fp)47     {48         fprintf(stderr, "open file fail\n");49         return -1;50     }51     const char cmd[] = "this line shall written into file!\n";52     printf("this line shall written into file!\n");53     printf("this line shall written into file! more args %p\n", fp);54 #endif55     return 0;56 }

 

转载于:https://www.cnblogs.com/Five100Miles/p/9096124.html

你可能感兴趣的文章
使用BabeLua3.x在cocos2d-x中编辑和调试Lua
查看>>
框架页面jquery装载
查看>>
[十九]JavaIO之PipedReader 和 PipedWriter
查看>>
【推荐】使用Ultrapico Expresso学习正则表达式
查看>>
第八周例行报告
查看>>
捕获Camera并保存图片到本地(照相功能) -samhy
查看>>
POJ 3174 暴力枚举
查看>>
OTS parsing error: invalid version tag woff和ttf文件被Filter拦截
查看>>
SDK开发日积月累(二)
查看>>
python - 字符串的格式化输出
查看>>
LINQ to SQL语句之 Count/Sum/Min/Max/Avg
查看>>
常见存储过程分页PK赛——简单测试分析常见存储过程分页速度
查看>>
SpringMvc+ajax实现文件跨域上传
查看>>
hive基本操作与应用
查看>>
数位DP
查看>>
第九周进度
查看>>
linux 环境配置 安装jdk
查看>>
Windows 消息循环(1) - 概览
查看>>
了解C++默默编写并调用哪些函数
查看>>
pandas中DataFrame的ix,loc,iloc索引方式的异同
查看>>