C语言输入与输出
基础知识
C语言中所有输入输出都用流(stream)完成。流按行组织字符序列,每一行用一个换行符结束。至少3种流与程序连接:stdin,stdout,stderr。一个流是内存中的一个缓冲区,程序运行中输入输出数据都被收集在相应缓冲区中。
字符数据的输入
1.输入单字符函数getchar:从标准输入流stdin中当前读入位置读入一个字符(包括空格、\n、Tab),读取成功返回该字符编码,出错或遇到EOF则返回-1。成功读入后stdin当前读入位置自动后移一个字符。
2.getchar是带参数的类函数宏定义:
#define getchar() getc(stdin)
字符数据的输出
1.输出单字符函数putchar:将程序中的一个字符的编码不加处理地送到标准输出流stdout的当前输出位置,并把对应的符号显示在屏幕上。正确时返回送出的字符编码,出错时返回-1。成功后将stdout当前位置后移一个字符。
2.putchar是带参数的类函数宏定义:
#define putchar(c) putc(c,stdout)
3.参数总是按无符号整数解释。在0~255之外的值按256取模。
//输出换行符 putchar('\n'); putchar('\12'); putchar('\xa');
格式化输出
1.格式化输出函数printf:将调用时给出的输出项按指定的格式转换为字符序列送到stdout并在屏幕上显示。返回值为实际输出的字符个数。
printf(格式控制字符串,输出项表)
2.格式控制字符串包括转换说明(% 转换修饰符 转换说明符)和普通字符。这里不再赘述。
3.输出项表:由若干个输出项构成,各输出项之间用逗号分隔。
4.pritnf函数工作原理:执行printf函数时,首先计算各个输出项的值,但各个编译器求值顺序可能不同。每个输出项表达式求值后按其结果类型被顺序储存到“堆栈”。然后扫描格式控制字符串,若遇到非转换说明则直接把该字符放入输出缓冲区的当前位置;当遇到转换说明时,则按指出的类型从堆栈中取出对应长度的数据,按要求转换成字符序列顺序放入输出缓冲区(buffer)。最后把输出缓冲区中加工好的内容传送到屏幕上。
把输出缓冲区内容传送到屏幕称为刷新缓冲区(flushing the beffer),C标准规定了输出缓冲区三种情况:
①当输出缓冲区满时
②当遇到换行符时
③当有新的输入请求时
5.printf输出不同类型数据:
①输出整数:
- 采用%d输出long型数时,只取该数的低16位;
- 以八进制或十六进制输出整数是将整型数的所有位(包括符号位)按对应形式输出,因此输出的数值不带符号;
- 当输出字符个数大于域宽修饰符时,域宽修饰符无效;
- 域宽不足时整数输出右端补以空格;
②输出实数:
- 使用%e, %g输出实数若使用精度修饰符(.n), n指有效数字位数;
③输出字符:
- 若输出数据为整型数,则把整型数理解成无符号数对256取模作为输出字符的编码;
④输出字符串:
- 使用%s将从第一个字符开始一直输出到字符串结束标志'\0'为止;
- 域宽修饰符小于字符串长度时域宽修饰符无效;
- 域宽修饰符小于精度修饰符时域宽修饰符无效;
#include<stdio.h> int main() { printf("%s", "hello \0 world"); return 0; } //输出"hello "
⑤ 修饰符" * ": 可以利用" * "暂时代替域宽或精度,其值由输出项表中对应的输出项决定, 如:
printf("%*.*f", x, y, z); //表示输出域宽x,精度y的浮点数z
格式化输入
1.格式化输入函数scanf:将从stdin读取的若干字符按格式字符串的转换说明转换为指定类型的数据,并保存到对应得输入项中。返回值为实际读入并成功转换的输入项个数。
scanf(格式控制字符串,输入项表)
2.格式控制字符串包括转换说明、普通字符和空白字符(空格、\n、Tab)。
- 普通字符用来指出输入输出流中字段间的特殊分隔符;
- 空白字符与输入流中作为数据分隔符的空白字符不必一一对应;
- 普通字符与输入流中作为数据分隔符的普通字符必须一一对应;
3.一个字段有以下几种含义:
- 由一系列非空白字符组成;
- 从stdin当前读入位置的第一个非空白字符起到下一个空白字符之间的读入字符;
- 从stdin当前读入位置的第一个非空白字符起到转换说明指定的宽度为止的已读入字符;
- 从stdin当前读入位置的第一个非空白字符起到一个当前转换说明不能转换的字符为止的已读入内容;
#include<stdio.h> int main() { int a = 10; scanf("%d", &a); printf("%d", a); return 0; } /* 输入12 -> 12 输入12a -> 12 输入a -> 10 */
4.输入项表:由若干地址组成,地址之间用逗号隔开。
5.scanf输入不同类型数据:
①输入整数:
- 使用%i可以接受十进制整数,八进制和十六进制常量书写形式的输入字段;
②输入浮点数:
- 不能使用精度修饰符输入指定精度的数据;
- %f和%e都可以用指数形式和小数形式输入数据;
- 输入double型数必须使用%lf或%le, 输入long double必须使用%Lf或%Le;
③输入字符:
- %c可以从键盘上输入任何字符,包括组合键;
④输入字符串:
- %s输入时总是从第一个非空白字符开始读入, 直到遇到空白字符停止读入;
- gets允许输入的字符序列中含有空格,总是以回车换行符或EOF结束输入;
# include <stdio.h> int main() { char str[30]; char ch; scanf("%s",str); printf("%s\n", str); scanf("%c", &ch); printf("ch=%c\n", ch); return 0; } /* 输入 hay 输出 hay ch= */
# include <stdio.h> int main() { char str[30]; char ch; gets(str); printf("%s\n", str); scanf("%c", &ch); printf("ch=%c\n", ch); return 0; } /* 输入 hay 输出 hay 输入 a 输出 a */
⑤赋值抑制符压缩修饰符" * "把正常读入的字段丢掉, 并不赋给某个输入对象, 如:
scanf("%d%*c%d%*c%d", &y, &m, &d);
⑥域宽修饰符: 从输入数据中截取与域宽值相同的字符数作为一个字段转换成指定类型的数据, 如:
scanf("%3d%4d%3c%c",&a, &b, &c, &d); 输入 1234567abcd 赋值 123 4567 a d