printf重定向

用到第三方库使用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 <string.h>
 2 #include <stdlib.h>
 3 #include <stdio.h>
 4 #include <fcntl.h>
 5 #include <stdarg.h>
 6 #define REDIRECT
 7 #undef REDIRECT
 8 #ifdef REDIRECT
 9 int fd = -1;
10 #else
11 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 buffering
26     return printf("%s\n", s);
27 }
28 */
29 #endif
30 int main()
31 {
32 #ifdef REDIRECT
33     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 detail
43     fsync(fd);
44 #else
45     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 #endif
55     return 0;
56 }

 

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

printf重定向是指将printf函数的输出从默认的显示器改为其他设备或文件。在C语言中,可以通过重定义fputc函数来实现printf重定向。具体来说,可以通过重定义fputc函数printf的输出重定向到串口、文件或其他设备上。 示例代码中使用了freopen函数来实现printf重定向。首先,通过调用freopen函数将标准输出(stdout)重定向到指定的文件或设备。例如,可以将printf的输出重定向到USART1串口,这样就可以将单片机的数据打印到PC上的超级终端或串口调试助手。然后,通过再次调用freopen函数将标准输出恢复为默认的显示器。 需要注意的是,重定义fputc函数是实现printf重定向的关键。在重定义的fputc函数中,可以将printf的输出数据重定向到指定的设备或文件,例如将数据重定向到ITM端口。 总结起来,printf重定向是通过重定义fputc函数来实现的,可以将printf的输出从默认的显示器改为其他设备或文件。 #### 引用[.reference_title] - *1* [printf函数重定向](https://blog.csdn.net/weixin_51121577/article/details/127337297)[target="_blank" data-report-click={"spm":"1018.2226.3001.9630","extra":{"utm_source":"vip_chatgpt_common_search_pc_result","utm_medium":"distribute.pc_search_result.none-task-cask-2~all~insert_cask~default-1-null.142^v91^control_2,239^v3^insert_chatgpt"}} ] [.reference_item] - *2* *3* [printf重定向的相关总结](https://blog.csdn.net/gogo0707/article/details/124652111)[target="_blank" data-report-click={"spm":"1018.2226.3001.9630","extra":{"utm_source":"vip_chatgpt_common_search_pc_result","utm_medium":"distribute.pc_search_result.none-task-cask-2~all~insert_cask~default-1-null.142^v91^control_2,239^v3^insert_chatgpt"}} ] [.reference_item] [ .reference_list ]
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值