C语言的格式化输入输出靠的是printf和scanf函数,在stdio.h头文件。

格式化输出:

Printf具有返回值,值为本次调用字符的个数,包括回车等控制符。

看一种使用方式:int i =5; Printf("%d",i);就是将整型变量i替换到字符串中,输出的结果也就是5。理所当然地,还可以Printf("%d,%d,%d,%d",i1,i2,i3,i4);前面的%d称为占位符,就是这个位置是为后面的i留着的,前面占了多少个位置,后面就必须有多少个变量,一个萝卜一个坑。

%d - 0 m.n |或者h 格式字符
//%转换说明的开始(占位符)
//-表示左对齐,默认是右对齐。
//0表示空位填0,省略则空位不填。
//m.n : m是域宽,指对应的输出项在输出设备占用多少个字符的宽度。n是精度,输出浮点数的时候,小数点后面的位数,默认是6。
//l或者h :l整数,long;浮点数,double。h将整数的格式修整为short。


常用例子:

Printf("%d\n",7);
Printf("%4d\n",7);//数字占四个位置
Printf("%-4d\n",7);//-表示数字左对齐
Printf("%04d\n",7);//没有占满的位置用0
Printf("%d,%c\n",'a','a');//字符类型数据%c,字符用ASCLL码表存储,%c的时候编译器会去查表。%d则直接输出数字。
Printf("%f\n",1.5f);//浮点类型数据用%f
Printf("%5.2\n",1.5f);//一共占五个位置,小数点占后两位
Printf("%lf\n",1.5);//双精度浮点数用%lf表示
printf("整型:%i\n浮点型:%f\n符号:%c\n",123,45.6,'$');
printf("十六进制%x, 八进制%o\n", 763, 763);
printf("float/double去掉了尾随的0:%g\n",45.6);


格式字符:

    %c和%hhd: char
%c和%hhu: unsigned char
%c对应字符身份,%hhd和%hhu对应数字身份
%hd short
%hu unsigned short
%hx: 以16进制的 输出short类型的整数
%i/%d: int
%u: unsigned int
%ld long
%lu unsigned long
%x/%o: 十六进制/八进制
%#x/%#o: 显示各进制数前缀
%f/%lf: float/double
%g/%lg: float/double去掉了尾随的0
%s: "string"
%p: address
%e: 指数形式,科学计数法
%nd也可以作为占位符打印整数数字,n是一个整数。打印结果一定占n个位置,空位置补充空格字符
%-nd打印结果也占n个位置,空位置出现在右边
%0nd打印结果也占n个位置,空位置用字符‘0’填充
%n.mf可以用来打印浮点数,打印结果中整个数字占n个位置,小数点后面占m个位置


标准输出宽度占13位,小数点前一位(非零),小数点占一位,6位小数,e占一位,指数符号占一位,指数占三位。

分隔符:空格,Tab, 回车。

格式化输入scanf:

scanf函数可以从键盘上读取用户输入的内容并把它记录到变量中。它需要变量的地址作为参数。忘记&操作符即发生段错误(程序段、数据段、bss段、堆栈、访问非法地址)。

如果用scanf读取字符串到字符数组中,则不加&

Scanf("%d",&i);//后面跟地址,不能用变量名。如果输入字母,则不知道怎么办,就不读了。而且一次输入错了如果不处理则后面的输入都无效。

’ : 输入抑制字符,表示该格式说明要求输入数据,但不赋值,即在地址列表中没有相应的地址项
Scanf(“%3d%
5d%f”,&a,&x);

输入2001200 4.1

则200赋给a,4.1赋给x,1200被跳过不赋给任何变量

scanf寻找数据的起始地址时,会跳过空白符(空格,回车,制表符等)。

scanf不会读取最后的换行符,解决办法:scanf("%*c");//可以将回车从缓冲区读取出来。

Width:宽度指示符,表示该输入数据所占列数,系统将自动按它截取所需数据。如遇空格或不可转换的字符,读入的字符将减少

有分隔符时,输入时需要输入对应的符号。

  int age;
float assets;
char pet[30];
printf("Enter your age, assets, and favorite pet.\n");
scanf("%d %f", &age, &assets);
// 这里要使用&
scanf("%s", pet);
// 字符数组不使用&
printf("%d $%.2f %s\n", age, assets, pet);


%i和%d的区别:

在printf里面没区别

在scanf里面:%d只匹配十进制,%i匹配八进制,十进制,十六进制。

缓冲区

缓冲区分为:

完全缓冲:填满刷新缓冲区,发送内容。常用于文件。大小取决于系统。

行缓冲:遇到换行符刷新。常用于键盘输入,Enter。

无缓冲:有些系统输入立即输出。

输入缓冲区:

只有当其中的数据读走的时候,才会清除这个数据。

scanf(数据类型)和缓冲区中的数据类型不一致的时候,便无法读走数据,可能导致死循环。

解决办法:

scanf("%*[^\n]");

*忽略读到的内容,[^\n]任何非\n的字符。

scanf调用失败返回0。

输出缓冲区:

程序->输出缓冲区->屏幕

<1>\n

<2>程序结束

<3>输出缓冲区满(4kb)

<4>人工刷新(fflush)

例子代码:

#include <Windows.h>
#include <stdio.h>


int main()
{
double d = 1.5e30;
printf("整型:%i\n浮点型:%f\n符号:%c\n",123,45.6,'$');
printf("十六进制%x, 八进制%o\n", 763, 763);
printf("float/double去掉了尾随的0:%g\n",45.6);
printf("**************\n\n");
/////////////指数//////////////////
printf("d as double:%g\n", d);
printf("d as integer:%d\n", d);
printf("d as e:%e\n",d);

//////////////类型转换/////////////////
printf("**************\n\n");
printf("%d\n", (int)d);
printf("\n****************************************\n\n");

///////////////scanf//////////////////
int age;
float assets;
char pet[30];
printf("Enter your age, assets, and favorite pet.\n");
scanf("%d %f", &age, &assets);
// 这里要使用&
scanf("%s", pet);
// 字符数组不使用&
printf("%d $%.2f %s\n", age, assets, pet);
printf("\n****************************************\n\n");

////////////////printf////////////////
printf("%d\n",7);
printf("%4d\n",7);//数字占四个位置
printf("%-4d\n",7);//-表示数字左对齐
printf("%04d\n",7);//没有占满的位置用0
printf("%d,%c\n",'a','a');//字符类型数据%c,字符用ASCLL码表存储,%c的时候编译器会去查表。%d则直接输出数字。
printf("%f\n",1.5f);//浮点类型数据用%f
printf("%5.2\n",1.5f);//一共占五个位置,小数点占后两位
printf("%lf\n",1.5);//双精度浮点数用%lf表示



system("pause");
return 0;
}