重定向函数的理解

在 C 语言标准库中, fputc 函数是 printf 函数内部的一个函数,功能是将字符 ch 写入到文件指针 f 所指向文件的当前写指针位置,简单理解就是把字符写入到特定文件中。我们使用USART 函数重新修改 fputc 函数内容,达到类似“写入”的功能。

fgetc 函数与 fputc 函数非常相似,实现字符读取功能。在使用 scanf 函数时需要注意字符输入格式。

还有一点需要注意的,使用 fput 和 fgetc 函数达到重定向 C 语言标准库输入输出函数必须在 MDK 的工程选项把“Use MicroLIB”勾选上, MicoroLIB 是缺省 C 库的备选库,它对标准 C 库进行了高度优化使代码更少,占用更少资源。

///重定向 c 库函数 printf 到串口,重定向后可使用 printf 函数
int fputc(int ch, FILE f)
{
/
发送一个字节数据到串口 */
USART_SendData(DEBUG_USARTx, (uint8_t) ch);

/* 等待发送完毕 */
while (USART_GetFlagStatus(DEBUG_USARTx, USART_FLAG_TXE) == RESET);

return (ch);
}

///重定向 c 库函数 scanf 到串口,重写向后可使用 scanf、 getchar 等函数
int fgetc(FILE f)
{
/
等待串口输入数据 */
while (USART_GetFlagStatus(DEBUG_USARTx, USART_FLAG_RXNE) == RESET);

return (int)USART_ReceiveData(DEBUG_USARTx);
}

重定向

即自己重写C的库函数

        提示

                链接器检查到用户编写了与C库函数相同名字的函数时,优先调用用户编写函数,这样就可实现重定向

重定向printf()函数

     需重写fputc()这个c标准库函数(printf()在c标准库函数实质是一个宏,实际是调用fputc()函数)

     说明

            fputc()默认是把字符输出到调试器控制窗口,要把数据通过USART输出到串口助手,需对基于fputc()的printf()系列函数的输出都重定向到USART端口上去

            要想使用USART功能,需重定向fputc()函数

参考代码

#include <stdio.h> 
 
#ifdef __GNUC__
 
#define PUTCHAR_PROTOTYPE int __io_putchar(int ch)
#else
#define PUTCHAR_PROTOTYPE int fputc(int ch, FILE *f)
#endif
 
//预处理实现Linux与Windows的兼容,不同的操作系统函数名不一样
 
PUTCHAR_PROTOTYPE
 
{
   USART_SendData(EVAL_COM1, (uint8_t) ch);
   while (USART_GetFlagStatus(EVAL_COM1, USART_FLAG_TC) == RESET)return ch;
 
}

FILE *f 文件操作

     前提概要   

         C语言自己的fputc的实现与单片机方式的fputc不一样,单片机使用printf需调用fputc这个C语言标准函数,而标准函数的参数就是int ch 和 FILE *f,f这个指针变量未使用,是因为在单片机不需要操作文件,但是标准的C里面是有,加上FILE *f只是为了能够使用fputc函数,如果没有FILE *f这个指针变量 fputc不能被重定向

     提示

            函数传递的参数,在函数内部可以不用,但必须保持函数名和参数的一致

return ch;

 说明

       fputc函数需返回值,以判断是否正常打印数据,成功就返回打印数据,这里未做判断直接进行了return

 提示

         单片机中重定向可参考我的博客

                https://blog.csdn.net/linxi8693/article/details/88187460

为什么可通过重写fputc实现printf的重写

printf是库函数,printf调用了fputc库函数,重写fputc函数即可实现重写printf

    重写跟链接有关

        不同的库中可有相同函数的实现(先被链接的会被使用)

            内存分配库有用该原理(重写malloc, free, operator new、delete等)

    相同函数名在同库中只能实现一次(多重定义会报重复定义错误)

Linux下的 fputc

fputc的实现应该在系统库(glibc)中

printf的输出是文件描述符stdout(stdout默认输出到屏幕)
    可以将stdout这个变量设为磁盘文件的文件描述符(输出到文件)
  • 2
    点赞
  • 7
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值