1.三种输出格式&格式控制字符&printf的缓冲&不同os缓存机制
me:转义字符和格式控制符,转义字符的出现:转义字符是字符,这个字符有特殊的含义,原则上所有字符都可以用程序表达出来,比如abc,可是有一些字符如回车换行,得用特殊字符表达,就是转义字符。
格式控制符是控制输出的格式。
3个函数用于输出:
在C语言中,有三个函数可以用来在显示器上输出数据,它们分别是:
- puts():只能输出字符串,并且输出结束后会自动换行//output string的缩写
- putchar():只能输出单个字符,在《C语言处理英文字符》中已经进行了介绍。
- printf():可以输出各种类型的数据,在前面的很多章节中都进行了介绍。
格式控制符:
格式控制符 | 说明 |
---|---|
%c | 输出一个单一的字符 |
%hd、%d、%ld | 以十进制、有符号的形式输出 short、int、long 类型的整数 |
%hu、%u、%lu | 以十进制、无符号的形式输出 short、int、long 类型的整数 |
%ho、%o、%lo | 以八进制、不带前缀、无符号的形式输出 short、int、long 类型的整数 |
%#ho、%#o、%#lo | 以八进制、带前缀、无符号的形式输出 short、int、long 类型的整数 |
%hx、%x、%lx %hX、%X、%lX | 以十六进制、不带前缀、无符号的形式输出 short、int、long 类型的整数。如果 x 小写,那么输出的十六进制数字也小写;如果 X 大写,那么输出的十六进制数字也大写。 |
%#hx、%#x、%#lx %#hX、%#X、%#lX | 以十六进制、带前缀、无符号的形式输出 short、int、long 类型的整数。如果 x 小写,那么输出的十六进制数字和前缀都小写;如果 X 大写,那么输出的十六进制数字和前缀都大写。 |
%f、%lf | 以十进制的形式输出 float、double 类型的小数 |
%e、%le %E、%lE | 以指数的形式输出 float、double 类型的小数。如果 e 小写,那么输出结果中的 e 也小写;如果 E 大写,那么输出结果中的 E 也大写。 |
%g、%lg %G、%lG | 以十进制和指数中较短的形式输出 float、double 类型的小数,并且小数部分的最后不会添加多余的 0。如果 g 小写,那么当以指数形式输出时 e 也小写;如果 G 大写,那么当以指数形式输出时 E 也大写。 |
%s | 输出一个字符串 |
%p | 它表示以十六进制的形式(带小写的前缀)输出数据的地址。如果写作%P ,那么十六进制的前缀也将变成大写形式 |
printf() 格式控制符的完整形式如下:
%[flag][width][.precision]type
eg:%-9d
中,d
表示以十进制输出,9
表示最少占9个字符的宽度,宽度不足以空格补齐,-
表示左对齐。综合起来,%-9d
表示以十进制输出,左对齐,宽度最小为9个字符。大家可以亲自试试%9d
的输出效果。
从本质上讲,printf() 执行结束以后数据并没有直接输出到显示器上,而是放入了缓冲区,直到遇见换行符\n
才将缓冲区中的数据输出到显示器上。
Windows 和 Linux、Mac OS 的缓存机制不同。
要想破解 printf() 输出的问题,必须要了解缓存,它能使你对输入输出的认识上升到一个更高的层次,以后不管遇到什么疑难杂症,都能迎刃而解。可以说,输入输出的“命门”就在于缓存。
2.使用scanf从键盘输入数据
scanf 是 scan format 的缩写,意思是格式化扫描,也就是从键盘获得用户输入,和 printf 的功能正好相反。
在C语言中,有多个函数可以从键盘获得用户输入:
本质上讲,用户输入的内容都是字符串,scanf() 完成的是从字符串中提取有效数据的过程。
从本质上讲,我们从键盘输入的数据并没有直接交给 scanf(),而是放入了缓冲区中,直到我们按下回车键,scanf() 才到缓冲区中读取数据。如果缓冲区中的数据符合 scanf() 的要求,那么就读取结束;如果不符合要求,那么就继续等待用户输入,或者干脆读取失败。
- scanf():和 printf() 类似,scanf() 可以输入多种类型的数据。
- getchar()、getche()、getch():这三个函数都用于输入单个字符。
- gets():获取一行数据,并作为字符串处理。
scanf("%d %d", &a, &b); // 获取用户输入的两个整数,分别赋值给变量 a 和 b
printf("%d %d", a, b); // 将变量 a 和 b 的值在显示器上输出
用户每次按下回车键,程序就会认为完成了一次输入操作,scanf() 开始读取用户输入的内容,并根据格式控制字符串从中提取有效数据,只要用户输入的内容和格式控制字符串匹配,就能够正确提取。
字符串的两种定义形式,它们分别是:
char str1[] = "http://c.biancheng.net";
char *str2 = "C语言中文网";
这两种形式其实是有区别的,第一种形式的字符串所在的内存既有读取权限又有写入权限,第二种形式的字符串所在的内存只有读取权限,没有写入权限。printf()、puts() 等字符串输出函数只要求字符串有读取权限,而 scanf()、gets() 等字符串输入函数要求字符串有写入权限,所以,第一种形式的字符串既可以用于输出函数又可以用于输入函数,而第二种形式的字符串只能用于输出函数。
scanf() 格式控制符汇总
格式控制符 | 说明 |
---|---|
%c | 读取一个单一的字符 |
%hd、%d、%ld | 读取一个十进制整数,并分别赋值给 short、int、long 类型 |
%ho、%o、%lo | 读取一个八进制整数(可带前缀也可不带),并分别赋值给 short、int、long 类型 |
%hx、%x、%lx | 读取一个十六进制整数(可带前缀也可不带),并分别赋值给 short、int、long 类型 |
%hu、%u、%lu | 读取一个无符号整数,并分别赋值给 unsigned short、unsigned int、unsigned long 类型 |
%f、%lf | 读取一个十进制形式的小数,并分别赋值给 float、double 类型 |
%e、%le | 读取一个指数形式的小数,并分别赋值给 float、double 类型 |
%g、%lg | 既可以读取一个十进制形式的小数,也可以读取一个指数形式的小数,并分别赋值给 float、double 类型 |
%s | 读取一个字符串(以空白符为结束) |