C语言的printf和scanf用法

2024 年 7 月 31 日 星期三(已编辑)
/ , ,
21
2
摘要
C 语言中的输入输出函数包括 printf、scanf、putchar、getchar、puts 和 gets 等。printf 用于简单字符串输出,通过占位符实现格式化输出,如 %d、%s、%f 等。scanf 用于输入,可以通过设置占位符将输入赋值给对应的变量。putchar 用于输出单个字符,getchar 用于获取用户输入的字符。puts 用于输出字符串,并自动换行。gets 用于读取用户一行输入,不跳过空白字符,遇到换行符结束。
这篇文章上次修改于 2024 年 8 月 21 日 星期三,可能部分内容已经不适用,如有疑问可询问作者。

C语言的printf和scanf用法

一.printf()

1.基础语法

用于简单的字符串的输出

// printf 可用于字符的输出
printf("hello world");
printf("hello\nworld\n");
printf("hello\n");
printf("world\n");

2.占位符

在其他的语言中也可以被成为模板语法,当我们需要输出变量或者表达式的值的时候,就可以使用占位符来完成这件事,通过在 printf 函数的第一个参数中增加 %【x】 实现占位操作。

// 单个占位符
printf("This is a simple el %c\n",'!');
    
// 多个占位符(两个占位符刚好与2,3参数对应)
printf("%s is s%c\n","aQ",'b');
    
// 多个占位符(两个占位符不与2,3参数对应)
// ----这种情况下多余的 %s 占位符会输出内存中的任意值
    
// [错误写法但是可以运行] printf("%s is %s","aglorice");

常见的占位符类型有以下几种:

  • %c:字符。
  • %d:整数。
  • %f:float类型浮点数。
  • %lf:double类型浮点数。
  • %Lf:long double类型浮点数。
  • %s:字符串。
  • %e(%E): 浮点数指数输出[e-(E-)记数法]
  • %g(%G): 浮点数不显无意义的零"0"
  • %[]:在方括号中指定一组匹配的字符(比如%[0-9]),遇到不在集合之中的字符,匹配将会停止。
printf("%e\n",0.00123); // 1.23e-03
printf("%e\n",12.231);  // 1.2231e+01
printf("%e\n",12123.23123123); // 1.212323e+04
printf("%E\n",123.123); // 1.23123E+02
printf("%g\n",23.23400);// 23.234

对于一些特殊的有:

  • %%: 输出一个%号。
  • #: 对于oxorX可以输出完整的前缀。
  • %o: 输出一个八进制的数。
  • %x or %X:输出一个十六进制的数。
int a = 5;
printf("%%%d\n",a); // %5
printf("%#X\n",a);  // 0X5
printf("%#o\n",a);  // 05
printf("%O\n",a);   // 5
printf("%x",a);     // 5

其中我们需要特别注意%s,当字符串中出现\0时,就会停止输出后续的字符,例如:

printf("%s","hello\0world");

那么就只会输出如下的结果。

hello

还需要注意的一个点就是当我们错误的将错误的使用占位符,例如:本来我们使用的是一个整形的占位符,但是传入的值是一个非整形的变量或者表达式,那么就会造成一些意想不到的情况。例如:

printf("%f",12);
print("%d",12.3);

结果可能和想象的不太一样。

0.000000
这个值不确定,每次运行的结果都不一样。

那这是为什么呢?

3.输出格式

1.限定宽度

在输出语句中,我们可以使用%[number][x]格式化字符串来限定输出字符的宽度,默认是向右对齐的,当然也可使用%-[number][x]来改变对齐方式,也就是向左对齐。

printf("%10s\n","aglorice");
printf("%-10s\n","aglorice");
printf("%12f\n",123.1);

输出结果如下:

  aglorice
aglorice
  123.100000

2.显示正负号

在c语言中默认不显示正号,但是我们可以通过%+[number][x]格式化字符串来显示数字的正号,感觉也没啥用。

printf("This is a number %+4d\n",12);
printf("This is a number %+d\n",12);
printf("This is a number %+d\n",-123);

输出结果如下:

This is a number  +12
This is a number +12
This is a number -123

3.限制小数点的位数

比如实现一个保留两位小数。

printf("%.2f",3.141592);

4.保留部分字符串

如果我们需要控制输出字符串的长度就可以使用这种方式来控制输出字符串的长度,(注意:方向是从左往右)。

printf("%.8s","hell\nworld\n");

输出结果如下:

hell
wor

5.指定保留的小数点的位数或者字符宽度

通过前面的了解,我们发现,所有的输出格式,好像只能固定不动,但是在c语言中,我们可以使用c语言提供的一个* 占位符实现动态的改变如字符宽度,小数点位数等等。

甚至我们可以通过刚刚介绍的内容写出下面的输出语句。😅,真的有人会这样写代码吗。

printf("%+-*.*f\n",10,2,2.1123);

输出结果如下(>﹏<)

+2.11

6.自动补0

当我们使用限制宽度的时可能会出现有效输出前面是空格的情况,显然这种方式很不美观,我们可以使用如下的方式来实现自动补0,且不需要自己实现。

printf("%08d",1234);

结果如下

00001234

二.scanf()

1.基础语法

int a = 0;
scanf("%d",&a);

2.占位符

这里和前面说的printf占位符差不多一样。

3.匹配规则

通过设置占位符,我们可以把我们想要的类型赋值给对应的变量,那么他是怎样处理的呢,在scanf()处理数值占位符时,会自动过滤空白字符,包括空格、制表符、换行符等。所以,用户输入的数据之间,有一个或多个空格不影响scanf()解读数据。另外,用户使用回车键,将输入分成几行,也不影响解读。

int year,month,day;
scanf("%d%d%d",&year ,&month,&day);
printf("%d-%d-%d",year,month,day);

下面这样的输入方式也是正确的。 bash 2024 12 12

如果有多个scanf语句的话,由于scanf并不是直接通过键盘获取用户的输入,而是从缓冲区里面取,和文件的读操作类似,当一个scanf运行完成后,下一个scanf语句会继续从上一个scanf结束的位置的下一位开始匹配。

特别注意,scanf只会自动忽略空白字符,包括空格、制表符、换行符等,前面已经说过了,但是对于字符是不行的。例如:

int a,b;
scanf("%d%d",&a,&b);

接下来我们输入数据。

//第一种(错误)
123,123
//第二种(正确)
123 123

4.赋值忽略符

例如,我们有一个需求,需要用户输入年月日分别保存到对应的变量并输出。

int year,month,day;
scanf("%d-%d-%d",&year ,&month,&day);
printf("%d-%d-%d",year,month,day);

这个时候,我们只需要输出2024-12-12 就可以读取对应的年月日,但是如果有的用户输入的是2024/12/12,看上去也挺合理的,但是对于机器可能就不知道你在干嘛了,这个时候我们就可以使用赋值忽略符,他可以忽略指定的内容,例如这里我们是需要忽略的是一个字符,就可以这样做。

scanf("%d%*c%d%*c%d",&year,&month,&day);
scanf()的返回值是一个整数,表示成功读取的变量个数。如果没有读取任何项,或者匹配失败,则返回0。如果读取到文件结尾,则返回常量 EOF。

三.putchar(),getchar()

1.getchar()

基本用法

int ch;
ch = getchar();

特别注意的是,该函数从键盘上接受一个字符,返回的是一个整形,如果出现读取失败,则会返回一个EOF

2.putchar()

int a = 89;
putchar(a);
putchar('a');

顾名思义,输出一个字符,如果输出失败则会返回EOF.

四.puts()

用于输出一个字符串。

char a[100] = {'a','\0','b','\0'};
puts(a);
puts("asd\0asd");

也就相当于使用printf("%s",a),需要注意的是,puts()会自动换行。

五.gets()

gets()函数读取用户的一行输入,不会跳过起始处的空白字符,直到遇到换行符为止。这个函数会丢弃换行符,将其余字符放入参数变量,并在这些字符的末尾添加一个空字符\0,使其成为一个字符串。

六.sscanf(),sprintf()

1.sprintf()

作用 : 将格式化的数据写入指定字符数组。

int sprintf(char *str, const char *format, ...);

参数

  • str:目标字符数组,用于存储格式化后的字符串。
  • format:格式字符串,指定如何格式化输出。
  • ...:要格式化的变量,可以是多个参数。

返回值:返回写入字符数组的总字符数(不包括终止的空字符)。

#include<stdio.h>

int main() {
    char buff[4];
    sprintf(buff,"%#x",29);
    printf("%s",buff);
    return 0;
}
这也意味着我们可以使用这种方式来连接字符串数字转字符串,功能相当强大。

2.sscanf()

作用:从指定的字符串中格式化输入。

int sscanf(const char *str, const char *format, ...);

参数:

  • str:源字符串,从中读取数据。
  • format:格式字符串,指定如何解析输入。
  • ...:用于存储读取结果的变量。

返回值:返回成功读取的项数。如果没有读取到任何数据,返回 0;如果发生错误,返回 EOF。

#include<stdio.h>

int main(){
  int n = 0;
    char *s = "8";
  sscanf(s,"%d",&n);
  printf("%d",n);
  return 0;
}

也就是说,我们可以实现下面的操作。

#include<stdio.h>

int main() {
    char buff[10]={0},n= 0;
    // 十进制转8进制
    sprintf(buff,"%o",123);
    sscanf(buff,"%d",&n);
    printf("%d\n",n);
    // 十六进制转十进制
    strcpy(buff,"1B");
    sscanf(buff,"%X",&n);
    printf("%d",n);
}

使用社交账号登录

  • Loading...
  • Loading...
  • Loading...
  • Loading...
  • Loading...