相关文章推荐
年轻有为的生菜  ·  VBA EXCEL ...·  9 月前    · 
自信的凳子  ·  python滤波器 ...·  11 月前    · 
微醺的墨镜  ·  【已解决】c# ...·  1 年前    · 

printf为C语言中的库函数,需要包含头文件stdio.h,能够发送格式化输出到标准输出stdout,printf函数的声明如下。

printf函数的定义调用了fputs函数
我们在STM32单片机上面使用printf函数时,需要对fputs进行重定向,重定向为输出到串口,然后再通过串口转USB把数据输出到电脑上串口工具

u8 print_level=2;//打印开关
FILE __stdout;   
//加入以下代码,支持printf函数
#pragma import(__use_no_semihosting)         
//标准库需要的支持函数
struct __FILE 
	int handle; 
//定义_sys_exit(),以避免使用半主机模式
void _sys_exit(int x) 
	x = x; 
void _ttywrch(int ch)
	ch = ch;
//重定向fputs函数
int fputc(int ch, FILE *f)
	USART_ClearFlag(USART6,USART_FLAG_TC);
	USART_SendData(USART6, (unsigned char) ch);// USART1 ???? USART2 ?
	while (!(USART6->SR & USART_FLAG_TXE));
	return (ch);

名词解析
stdout fputs函数

要弄清什么是标准输入输出。首先需要弄懂什么是IO。
IO的I是Input的意思,O是output的意思。
意味着输入和输出。
更确切的含义是
I:从外部设备输入到内存
O:从内存输出到外部设备

而标准输入和标准输出是干什么的?它们是用于IO的。
那么它们属于IO的哪个部分?
内存?还是外部设备?
答案显然是外部设备(逻辑上的外部设备,为什么?接着看)。

更具体的含义?
在linux操作系统中,外部设备用什么表示?是用文件。
linux中一切设备皆是文件!
因此标准输入和输出更具体的含义是文件。

它们是哪两个文件?
它们是/dev/stdin这个文件和/dev/stdout这个文件。
也就是说所谓的标准输入和标准输出其实就是两个linux下的文件。

linux的文件类型有:
1、普通文件2、字符设备文件3、块设备文4、目录文件
5、链接文件6、管道文件7、套接字文件
思考一下?它们是什么文件?它们在/dev目录下,它们是设备文件吗?

那么所谓的从标准输入读是什么意思?
逻辑上来看:
就是打开/dev/stdin这个文件,然后把这个文件里的内容读进来。
输出到标准输出是什么意思?
逻辑上来看:
就是打开/dev/stdout这个文件,然后把内容输出到这个文件里去。

为什么是从逻辑上来看?因为它们不是设备文件!!!
所以它们不代表一个设备。linux里一切皆是文件,设备是文件,但是文件不一定是设备!
那它们是什么文件?他们是链接文件。(可以用ls -l /dev来查看 l开头的就是链接文件。)
什么是链接文件?文件内容是另一个文件的地址的文件称为链接文件。
因此,打开、读或者写 /dev/stdin和/dev/stdout 实际上是打开、读或者写这两个文件存放的地址对应的设备文件。

明白它们是链接文件不是设备文件有什么用?明白这一点才能知道重定向失效的原理

fputs函数
fputs()函数的第二个参数指明他要写入的文件。如果要在计算机显示器上打印,则使用stdout作为参数。与puts()函数不同,fputs()函数不会在待输出字符串末尾添加一个换行符。

#include <stdio.h>
#define LEN 14
int main(void){
    char words[LEN];
    puts("Enter a String");
    fgets(words,LEN, stdin);
    puts(words);  //puts()函数会添加换行符\n
    fputs(words, stdout);
    return 0;

我们在写C程序时经常遇到printf(),fprintf(),perror(),这些东西到底有什么作用。说到这不得不提及stdin,stdout,stderr。想想,我们在用C去写文件时的操作,File fp=fopen(),这个fp就是我们向系统申请的,相当于一通往文件的通道。其实,stdin,stdout,stderr就是这个fp,不过他是随着计算机系统的开启默认打开的,其中0就是stdin,表示输入流,指从键盘输入,1代表stdout,2代表stderr,1,2默认是显示器。printf()其实就是向stdout中输出,等同于fprintf(stdout,“”),perror()其实就是向stderr中输出,相当于fprintf(stderr,“”),那到底stdout,和stderr有什么区别和作用呢?

我们在写程序时用printf()是为了我们能监控我们的程序运行状况,或者是说debug,如果我们的程序是一直运行,不停下来,我们不可能时刻盯着屏幕去看程序输出,这时我们就可以用文件重定向。将输出到一文件中,我们以后就可以看这文件就行。举个例子,test.c
<pre class="cpp" name="code">#include<stdio.h>
int main()
     printf("stdout Helo World!!\n"); 
     return 0;

编译过后,我们./test > test.txt(默认是将stdout里的内容重定向到文件中),这样就把test程序输出的内容输出到test.txt文件中。还有一种更明晰的写法./test 1>test.txt,这里的1就代表stdout。说到这你应该知道stderr该怎样处理了。再举个例子test.c:

#include<stdio.h>
int main()
     printf("Stdout Helo World!!\n");
     fprintf(stdout,"Stdout Hello World!!\n");
     perror("Stderr Hello World!!\n");
     fprintf(stderr,"Stderr Hello World!!\n");
     return 0;

编译过后,./test,屏幕上是四条输出,如果./test > test.ext ,结果是屏幕上输出两条Stderr Hello World!!,Stdout Helo World!!在文件test.txt中,基于上面说的很容易理解现在的结果,于是我们可以随便处理我们想要的输出,例如:

./test 1>testout.txt 2>testerr.txt,我们将stdout输出到文件testout.txt中,将stderr输出到testerr.txt文件中;

./test 1>testout.txt ,将stdout输出到文件testout.txt 中,stderr输出到屏幕上;

./test 2>testerr.txt,将stderr输出到文件testerr.txt中,stdout输出到屏幕上;

./test > test.txt 2>&1,这是将stdout和stderr重定向到同一文件test.txt文件中。

如果我们不想看到输出内容,既不想在屏幕上看见,也不想重定向到文件中,别担心,万能的linux有解决办法,./test > /dev/zero 2>&1,这样就看不到任何输出了。

Note:stderr,和stdout还有重要一点区别,stderr是没有缓冲的,他立即输出,而stdout默认是行缓冲,也就是它遇到‘\n’,才向外输出内容,如果你想stdout也实时输出内容,那就在输出语句后加上fflush(stdout),这样就能达到实时输出的效果。

相关链接·:https://blog.csdn.net/wangyeqiang/article/details/38726433

printf为C语言中的库函数,需要包含头文件stdio.h,能够发送格式化输出到标准输出stdout,printf函数的声明如下。printf函数的定义调用了fputs函数我们在STM32单片机上面使用printf函数时,需要对fputs进行重定向,重定向为输出到串口,然后再通过串口转USB把数据输出到电脑上串口工具u8 print_level=2;//打印开关FILE __stdout; //加入以下代码,支持printf函数#pragma import(__use_no_semiho fp = fopen(“1.txt”, “r+”);//读写,除此之外用得比较多的有”a+”追加(也有读权限) if( NULL = fp) printf(“Failed to open the file”); ch = getchar(); //读写一个字符 fputc( 标准输入:表示键盘输入,其实在我看来标准输入就是从键盘上输入字符存储到一个文件中,可称为标准输入文件; 标准输出:表示显示屏,其实就是在程序的控制下将内存中的数据复制一份到标准输出文件; 标准错误输出:输出的设备还是显示屏,从内存中将输出的错误信息复制到标准错误输出文件(仅代表个人理解)。 2. 标准I/O库(stdio.h)中常见输入输出函数的使用。scanf printf scanf_s printf_s gets puts fgets fputs
根据前面的某一篇的文章,可以清楚的看到:对于每一个函数,通过这个函数的[ebp+x]就可以直接访问到它调用的时候传进来的形参的值,通过[ebp-x]就可以直接访问它的局部变量。 所以printf这个函数不定参数的实现是通过栈机制实现的,在传入实参的时候,从右向左一次把各个参数压入栈,但是这些压入栈的数据是没有类型区分的,就是把相应的数据依次放到栈中排好。最后压入栈的那个参数“%d%d%d”等类似...
C语言中fgets(...)从流中读入输入,相反fputs(...)向文件写入数据。      对于ANSI C 程序,运行时系统会打开至少三个流,这3个流包括:       1.   标准输入    standard input .    标准定义为stdin.       2    标准输出    standard output.   标准定义为stdout       3.   标准
#include int printf(const char *restrict format, ...); int fprintf(FILE *restrict fp, const char *restrict format, ...); 两个函数的返回值:若成功则
文章目录fgets()与fputs()1⃣️fgets()优缺点:2⃣️fgets()返回值:3⃣️fgets()操作实例:3⃣️fgets()操作进阶: fgets()与fputs() fgets()函数的第二个参数指明了读入字符的最大数量。如果该参数为n,那么fgets函数将读入n-1个字符。如果fgets()函数读到一个换行符,会把它储存在字符串中。这点与gets不同,gets会丢弃换行符...
fputs()函数是puts()函数针对文件定制的版本,它们的区别如下: fputs()函数的第2个参数指明要写入数据的文件。如果要打印在显示器上,可以用定义在stdio.h中的stdout(标准输出)作为参数。 与puts()不同,fputs()不会再输出的末尾添加换行符。 注意,gets()丢弃输入中的换行符,但是puts()在输出中添加换行符。另一方面,fgets()保留输入中的换行符,fputs()不在输出中添加换行符,因此,puts()应与gets()配
1. getchar()函数:从标准输入流中读取一个字符。 2. putchar()函数:向标准输出流中输出一个字符。 3. gets()函数:从标准输入流中读取一行字符串(包括空格)。 4. puts()函数:向标准输出流中输出一个字符串(自动添加换行符)。 5. fgets()函数:从指定文件流中读取一行字符串(包括空格)。 6. fputs()函数:向指定文件流中输出一个字符串。 7. scanf()函数:从标准输入流中读取格式化输入。 8. printf()函数:向标准输出流中输出格式化输出。 9. fscanf()函数:从指定文件流中读取格式化输入。 10. fprintf()函数:向指定文件流中输出格式化输出。