目录
printf函数
printf函数的一般格式
格式字符
注意事项
scanf函数
scanf函数的一般格式
注意事项
getchar函数和putchar函数
getchar函数的一般格式
putchar函数的一般格式
getchar函数的使用
putchar函数的使用
在C语言中,scanf和printf是输入和输出函数,在使用这两个函数时,需要指定输入数据的格式,根据不同类型的数据来指定不同的格式。
printf("格式控制",输出列表)
格式控制:由双引号所引起来的一个字符串,包含两个信息——格式声明和普通字符。
输出列表:需要输出的数据,可以是常量、变量、或者是表达式。
有时为了输出美观,会在格式控制里增加一些转义字符,例如在末尾加入换行符。
利用printf函数输出多个变量时,格式声明的顺序要和输出列表的顺序保持一致。
#include
int main()
{
int a = 10;//整型
double b = 2.0;//双精度
float c = 2.0f;//单精度,输入单精度时,要在末尾加上f,否则编译器会默认为double类型
printf("a=%d,b=%lf,c=%f\n", a,b,c);//输出多个变量时,格式声明的顺序要和输出列表的顺序一致
return 0;
}
当输出列表是表达式时,尽量做到表达式简洁,不要过度嵌套使用。
int sum(int x,int y)
{
return x + y;
}
#include
int main()
{
int a = 10;
int b = 20;
printf("sum=%d\n",a+b);
printf("sum=%d\n", sum(a, b));//表达式的形式多种多样,可以自行试验
return 0;
}
在输出时,对不同类型的数据要指定不同的格式声明。
格式声明的一般形式可以表示为:% 附加字符 格式字符
(例:%5d表示域宽为5的整数;%.2f为保留小数后两位小数)
注:附加字符可以不显示,但是%和格式字符是必须的。
格式字符 | 说明 |
---|---|
d | 输出带符号的十进制整数 |
ld | 输出带符号的十进制整数(长整型) |
u | 输出无符号的十进制整数 |
c | 输出一个字符 |
s | 输出字符串 |
f | 以小数形式输出,单精度 |
lf | 以小数形式输出,双精度 |
p | 地址 |
g | 以小数形式输出时,不输出无意义的0 |
e,E | 以指数形式输出实数。 用e时表示(1.2e+02) 用E时表示(1.2E+02) |
o | 以八进制无符号形式输出整数 |
x,X | 以十六进制无符号形式输出整数 用x时以小写字母输出; 用X时以大写字母输出。 |
字符 | 说明 |
l | 用于长整型整数、双精度小数,可加在格式符d、o、x、u、f前面 |
m | m表示为数据最小宽度(m为一个正整数) |
.n | 对实数,.n为表示输出n位小数 对字符串,.n为表示截取的字符个数(n为一个正整数) |
- | 输出的数字或字符在域内左对齐 |
1、printf函数输出时,输出的对象与对应类型必须匹配。
2、除特定格式字符外,其他格式字符必须使用小写。
3、在printf函数的“格式控制字符串”中可以加入转义字符。
4、格式字符以%为开头,以上述中格式字符之一为结束。
5、如果想输出%,应该在“格式控制字符串”中连续使用两个“%”表示。
例如:printf("%d%%",10);输出结果为10%
6、如果想输出的内容与转义字符混淆,在转义字符前加入\即可。
例如:如何输出一个\n呢?答:printf("\\n");
7、printf函数是有返回值的,他的返回类型是整型,大小为打印内容的个数。
scanf(格式控制,地址表列)
格式控制:含义同printf函数。
地址表列:是由若干个地址组成的表列,可以是变量、字符串的首地址。
地址表列的一般形式为& 参数名称,这里&为取地址符号。
例如:int a = 0;
scanf("%d",&a);
(1)scanf函数根据格式控制字符串的格式不同,所对应的输入方式也不同,并且scanf的格式控制中,不要随意加入转义字符,会导致输入出错。
例如:
int main()
{
int a = 0, b = 0, c = 0;
//假设我们想输入a=10,b=20,c=30
scanf("a=%d,b=%d,c=%d", &a, &b, &c);//a=10,b=20,c=30
printf("a=%d,b=%d,c=%d\n", a, b, c);
printf("--------------\n");
scanf("%d,%d,%d", &a, &b, &c);//10 20 30(每个数字之间用,隔开)
printf("a=%d,b=%d,c=%d\n", a, b, c);
printf("--------------\n");
scanf("%d%d%d", &a, &b, &c);//10 20 30(每个数字之间用空格或者回车隔开)
printf("a=%d,b=%d,c=%d\n", a, b, c);
return 0;
}
(2)输入数值时,两个数值之间需要插入空格或者回车,以使系统能够区分两个数值。但是在连续输入字符时,不要插入空格或其他分隔符,系统能够区分两个字符。
例如:
#include
int main()
{
char c1 = { 0 };
char c2 = { 0 };
char c3 = { 0 };
scanf("%c%c%c", &c1, &c2, &c3);//连着输入abc三个字符,按回车结束
printf("正确结果为:%c%c%c\n", c1, c2, c3);
printf("------\n");
getchar();//从缓冲区拿走一个字符
scanf("%c%c%c", &c1, &c2, &c3);//输入abc三个字符,每个字符之间用空格隔开
printf("错误的结果为:%c%c%c\n", c1, c2, c3);//err
return 0;
}
按F10进入调试,打开监视面板,对c1、c2、c3进行监视。
发现c1被赋值为‘a’,c2被赋值被‘ ’,c3被赋值为‘b’。在输入连续字符时,切勿加空格。
(3)在输入数值数据时,输入不属于数值的字符(例如:空格、回车、Tab等),认为数据结束。
#include
int main()
{
int a = 0;
char b = { 0 };
float c = 0.0f;
scanf("%d%c%f", &a, &b, &c);
printf("a=%d b=%c c=%f\n", a,b,c);
return 0;
}
假设输入1234z78 .23,第一个整型数值读取1234,到‘z’时发现是非数值字符便停止了;第二个字符正好读走一个‘z’;第三个浮点型数值读取78,到‘ ’时发现是非数值字符停止读取。
(4)用scanf函数输入一个数组
#include
int main()
{
int arr[10] = { 0 };
int i = 0;
for(i = 0; i < 10;i++)
{
scanf("%d", &arr[i]);
}
for (i = 0; i < 10; i++)
{
printf("%d", arr[i]);
}
return 0;
}
在编译器中,数组的下标是从0开始的,即第一个元素的下标为0,第二个元素下标为1.......第十个元素下标为9。这里对于数组的输入我们可以用for循环遍历输入,每次输入数组的一个元素,直到整个数组都输入完为止,数组的打印也是同理。
注:当数组为一个字符串时,可以直接输入、输出,并且因为数组名即数组的地址,所以调用scanf时不用加&符号。
例如:
#include
int main()
{
char arr[10] = { 0 };
scanf("%s", arr);
printf("%s", arr);
return 0;
}
除了printf和scanf输出和输入字符外,C语言的库函数中还有专门用来输入和输出字符的函数。
getchar函数的作用是从缓冲区获取一个字符,它的返回类型是整型。
getchar函数(字符输入函数)的一般形式为:getchar()
注:getchar函数的返回类型是整型,当getchar读取结束或者读取失败后会返回EOF,EOF的大小实际上是-1,所以需要创建一个整型变量来接收getchar。
putchar函数的作用是向显示器输出一个字符,它的返回类型的整型。
putchar函数(字符输出函数)的一般形式为:putchar(a)(意思为输出变量a的字符)
注:putchar(a)中的a可以是字符常量、整型常量、字符变量或整型变量(其值在字符的ASCII代码范围内)
主要用来清理缓冲区。
scanf和getchar函数都是从缓冲区里读取数据,把刚刚讲scanf的代码拿过来,比如我们想输入3个字符,分别是‘a’、‘b’、‘c’,当我们输入完abc后,scanf并不能读取到,还需要我们敲一下回车键,数据进去缓冲区后,scanf才能读取到。
#include
int main()
{
char c1 = { 0 };
char c2 = { 0 };
char c3 = { 0 };
scanf("%c%c%c", &c1, &c2, &c3);//连着输入abc三个字符,按回车结束
printf("正确结果为:%c%c%c\n", c1, c2, c3);
printf("------\n");
getchar();//从缓冲区拿走一个字符
scanf("%c%c%c", &c1, &c2, &c3);//输入abc三个字符,每个字符之间用空格隔开
printf("错误的结果为:%c%c%c\n", c1, c2, c3);//err
return 0;
}
在缓冲区中,除了我们想要的abc,还有我们敲回车键留下的\n,如果只进行一次数据输入并不会有任何影响。但是如果我们想连着输入两个数呢?假设我第二次想输入‘d’、‘e’、‘f’。第二个scanf首先会读取到缓冲区中留下的\n。
这时,第二个scanf首先会读取到前面留下来的\n,然后是de。想要解决掉这问题,只需要两次scanf之间加入getchar(),把换行符拿走即可。
然而,gerchar()每次只能拿走一个字符,如果需要拿走多个字符呢?
while ((ch = getchar()) != '\n')//清理缓冲区
{
}
while循环一直利用getchar读取字符,直到读取到\n时,缓冲区清理完毕。
例如:
做一个简易的密码输入程序
#include
int main()
{
char arr[10] = { 0 };
printf("请输入密码:>");
scanf("%s", arr);
int ch = 0;
while ((ch = getchar()) != '\n')//一直用getchar读取缓冲区内的字符,直到读取到\n时,缓冲区清理完毕
{
}
printf("密码是%s\n确认请按1,取消请按0\n",arr);
int ret = 0;
again:
scanf("%d", &ret);
switch (ret)//选择语句
{
case 1:
printf("确认成功\n");
break;
case 0:
printf("取消成功\n");
break;
default:
printf("输入错误,重新输入\n");
goto again;//如果输入错误,跳回again重新来
}
return 0;
}
设置一个char类型的数组,假设在输入密码时不小心输入了空格,例如w123 456,那么getchar会把后面的 456读取走,不影响后面scanf的输入。switch和goto语句在后期会学到。
putchar函数除了能够输出显示在显示器上的字符,也能够输入屏幕控制字符。
例如:putchar(‘\n’)的作用便是在屏幕上换行,作用与printf("\n")一样。
#int main()
{
char a = 'a', b = 'b', c = 'c';
int a1 = 97, b1 = 98, c1 = 99;
putchar(a);//直接输出字符
putchar(b);
putchar(c);
putchar('\n');//两种换行符
printf("\n");
putchar(a1);//利用ASCII码输出字符(putchar方式)
putchar(b1);
putchar(c1);
putchar('\n');
printf("\n");
printf("%c", a1); //利用ASCII码输出字符(printf方式)
printf("%c", b1);
printf("%c", c1);
return 0;
}
通过上述例子,我们还发现,putchar可以利用ASCII码值打印字符,只要其值在ASCII码的范围内即可(0~127)。而printf也有利用ASCII码输出字符的方式,以上三种方式输出的结果一致。
注:由于putchar是字符输出的函数,所以putchar(97)只能输出‘a’,而不能输出整数97。