字符串和格式化输入/输出 [printf & scanf]
一、字符串
C 语言中并没有专门用于储存字符串的变量类型,字符串都被存储在char类型的数组中。在数组中,会存在一个空字符(null character)【一个非打印字符,其 ASCII 码值是(或等价于)0】,C语言用其来标记字符串的结束。也就是说,char 型数组的容量必须比待存储字符串中的字符数多1。
strlen() 函数,对于计算字符串的长度,遇见空字符则停止计算,且空字符并不计算在内。与 sizeof 运算符有一定的区别。
二、printf ()
1 - 转换说明及其打印的输出结果
转换说明及其打印的输出结果
2 - 转换说明修饰符
printf() 修饰符 - 1
printf() 修饰符 - 2
printf() 标记
3 - 返回值
返回打印字符的个数。如果有输出错误,printf() 会返回一个负值(旧版本的不同,具体负值可能不同)。
4 - 打印较长的字符串的几种形式
方法一:使用多个 printf() 语句完成信息的输出。
示例:printf("Here id a way to print a ");
printf("long string. \n ");
方法二:用 ' \ ' 和 Enter (Return) 组合来断行。【下一行代码必须和程序清单中的代码一样从左边开始】
示例:printf("Here id a way to print a \
long string. \n");
方法三:ANSI C 引入的字符串连接,在两个用双引号括起来的字符串之间用空白隔开,C 编译器会把多个字符串看作是一个字符串。
示例:printf("Here id a way to print a " “long string. \n”);
三、scanf()
1 - 转换说明
ANSI C 中 scanf() 的转换说明
2 - 修饰符
scanf() 修饰符 - 1
scanf() 修饰符 - 2
3 - 返回值
scanf() 函数返回成功读取的项数。
如果没有读取任何项,且需要读取一个数字而用户缺输入一个非数值字符串,返回0。
当sacnf() 检测到 “文件结尾” 时,返回 EOF(EOF 是 stdio.h 中定义的特殊值)。
4 - 输入具体过程
如果使用的是 %d 转换说明,scanf() 每次读取一个字符时,跳过所有的空白字符,直至遇到第一个非空白字符(一个数字字符或者 + / - )才开始读取并保存,之后依次读取数字字符,直到遇到非数字字符,便认为读到了整数的末尾。此时,scanf() 把非数字字符放回输入,这也就意味着长须在下一次读取输入时,首先读取到的是上一次读取丢弃的非数字字符。最后,sacnf() 函数计算已读取数字(可能该有符号)相应的数值,并将计算后的值放入指定的变量中。
如果使用字段宽度,scanf() 会在字段结尾或第1个空白字符处停止读取(满足二者条件之一便可)。
其他转换说明,大多数与 %d 类似。
如果使用 %s 转换说明,scanf() 会读取除空白以外的所有字符。scanf() 跳过空白开始读取第1个非空白字符,并保存非空白字符直到再次遇到空白。也就意味着 scanf() 读取一个单词,其中不包括空白字符,当其将单词保存至具体的数组的时候,会自动再起末尾加上 '\0'。同样,如果是使用了字段宽度,与 %d 类似。
除了 %c ,其他转换说明都会自动跳过输入值前面所有的空白。
四、printf() 和 scanf() 中的 * 修饰符
1 - printf()
如果不想预先指定字段宽度,希望跳过程序指定,可以用 * 修饰符代替字段宽度,但是之后还是要在必要的地方提供一个字段宽度参数。也就是说,如果转换说明是 %*d ,那么参数列表中就一定要包含 * 和 d 的值。
2 - scanf()
把 * 放在 % 和转换字符之间时,会使得 scanf() 跳过相应的输入项。
[示例]
int n;
scanf("%*d %*d %*d", &n);
[输入: 2013 2014 2015]
[结果:n == 2015]
五、其他
1 - getchar() 与 putchar()
getchar()、putchar() 两个函数均只针对字符型数据。因为两者只处理字符,所以并不需要相应的转换说明。【这两个函数通常定义在 stdio.h 头文件中,而且,它们通常是预处理宏,而不是真正的函数。】