这期主要讲printf 和scanf 族类函数。
scanf函数部分
返回值
首先,这两个函数都是有返回值的,printf函数返回成功输出的字符个数,scanf函数返回成功接收的参数个数,如果接收到Ctrl + z, 代表文件末尾EOF, 返回-1。
#include<iostream>
int main(){
setvbuf(stdout,NULL,_IONBF,0);//针对Eclipse_for_C输出顺序问题,将缓存区空间设为0.
printf("一共输出了%d个字符\n", printf("123 456\n"));//printf函数返回输出字符个数
int num, a;
while((a = scanf("%d", &num)) != EOF){
printf("输入中取到%d个参数\n", a);
}
printf("EOF返回值or等价为%d\n", a);
return 0;
}
输出显示如下,其中666为输入。
空格、回车匹配
现在的问题是scanf函数一遇到费字符【空格,回车】,就会直接转为EOF??
实际上scanf函数是可以读入空格和回车的,其中如果格式化字符串中带有空格,如"\n%d", 就要先读入一个回车再输入数字。然后如果代码如下面形式:
scanf("%d", &x);
scanf("%c", &y);
则y会存放’\n’,想要吃掉回车不污染下面的输入,就要在上一句格式化字符串中加入回车,或者连在一起输入等等。参考博文:
那如何让scanf函数读入带空格字符串呢?这里要用到正则表达式,详细可以参考博文
https://blog.csdn.net/jeffasd/article/details/80705487
https://tieba.baidu.com/p/3167526276?red_tag=3185477910
类似的,表示取出所有非回车的字符代码:
scanf("%*[^\n]");//表示读入所有不是换行的字符串,这些都不保存,然后返回
scanf("%*c");//表示读入一个字符,但是这个字符不保存到变量里,这里表示取出\n
#include<iostream>
int main(){
setvbuf(stdout,NULL,_IONBF,0);
//int num;
char str[100] = {0};
while(scanf("%[^\n]s", str) != EOF){
scanf("%*c");//读入一个任意字符,用来吃掉回车
//getchar();//也是可以的
//scanf("%c");//也是可以的
//scanf("\n");//不可以!!!
printf("输出:%s", str);
}
return 0;
}
显示
有一个问题,不能使用scanf("\n")来吃掉回车,运行时,每次输入第二个语句,输出第一个语句,好像scanf在检测到回车以后仍然停留在原地,也没有清空缓存区。这是一个很奇怪的地方QAQ。
错误的输出显示:
限制输入长度:
限制长度以外的字符将被留在缓冲区,而且会匹配进下一次输入,%*d的意思是不计入变量,丢弃。
#include<iostream>
int main(){
setvbuf(stdout,NULL,_IONBF,0);
int a, b;
scanf("%4d %*d %d", &a, &b);
printf("a = %d\n", a);
printf("b = %d\n", b);
return 0;
}
显示:
1.
2.
3.
4.
遗留问题:
- 遇到空格和回车就EOF是什么机制?
- 上面只有回车的输入问题,以及scanf函数如果只有纯字符串,没有输入的%d之类,会如何?
printf函数部分
浮点数
double类记得匹配"%lf"型。
其他的看代码就可以。
#include<iostream>
int main(){
setvbuf(stdout,NULL,_IONBF,0);
float a = 1.25;
printf("%.1f\n", a);
printf("%8.3f\n", a);//小数点前代表总位数
printf("%08.3f\n", a);//用0补齐
printf("%8.8f\n", a);//位数不足时,先保证小数精度
printf("%g\n", a);//自动匹配
return 0;
}
显示:
sprintf 与fprintf
sprintf可以用于字符串拼接,类似:
sprintf(s,"%d + %d + %d", 1, 2, 3);
fprintf用于将输出重定向到文件中, 特殊的文件指针有stdout,stderr
fprintf(stdout, "hello! %s", "man");
会将输出打印到控制台上,与printf效果一样。