【C语言】printf() 和 scanf()

简介: 【C语言】printf() 和 scanf()

printf() 函数scanf() 函数,它们是输入/输出函数,或简称为 I/O 函数。

虽然 printf() 是输出函数, scanf() 是输入函数,但是它们的工作原理几乎相同

一、printf() 函数

       请求 printf()  函数打印数据的指令要与待打印数据的类型相匹配。例如,打印整数时使用 %d ,打印字符时使用  %c 。这些符号被称为转换说明(conversion specification ),它们指定了如何把数据转换成可显示的形式。

转换说明及其打印的输出结果:

二、使用 printf()

printf() 函数的格式:

printf( 格式字符串, 待打印项1, 待打印项2,...);


       待打印项 1 、待打印项  2  等都是要打印的项。它们可以是变量、常量,甚至是在打印之前先要计算的表达式。

格式字符串应包含每个待打印项对应的转换说明。格式字符串是双引号括起来的内容。

        注意格式字符串中的转换说明一定要与后面的每个项相匹配,若忘记这个基本要求会导致严重的后果。

如果只打印短语或句子,就不需要使用任何转换说明。

       由于 printf() 函数使用 % 符号来标识转换说明,因此打印 % 符号就成了个问题。如果单独使用一个% 符号,编译器会认为漏掉了一个转换字符。解决方法很简单,使用两个 % 符号就行了。

pc = 2*6 ;

printf("Only %d %% of Sally's gribbles were edible.\n", pc);

下面是输出结果

Only 12% of Sally's gribbles were edible.

三、printf() 的转换说明修饰符

printf() 的修饰符:

printf() 的标记:

1.使用修饰符和标记的示例

  • 字段宽度
#include <stdio.h>
#define PAGES 959
 
int main()
{
    printf("*%d*\n", PAGES);
    printf("*%2d*\n", PAGES);
    printf("*%10d*\n", PAGES);
    printf("*%-10d*\n", PAGES);
    return 0;
}

输出结果:(程序中使用星号(*)标出每个字段的开始和结束。)

*959*

*959*                // 其对应的输出结果应该是 2 字段宽度

                        // 因为待打印的整数有 3 位数字,所以字段宽度自动扩大以符合整数的长度。

*       959*        // 其对应的输出结果有10 个空格宽度        在两个星号之间有 7 个空格和 3 位数字

*959       *        // - 标记说明打印的数字位于字段的左侧。

  • 一些浮点型修饰符的组合
#include <stdio.h>
 
int main()
{
    const double RENT = 3852.99; // const变量
    printf("*%f*\n", RENT);
    printf("*%e*\n", RENT);
    printf("*%4.2f*\n", RENT);
    printf("*%3.1f*\n", RENT);
    printf("*%10.3f*\n", RENT);
    printf("*%10.3E*\n", RENT);
    printf("*%+4.2f*\n", RENT);
    printf("*%010.2f*\n", RENT);
    return 0;
}

该程序的输出如下:

*3852.990000*        // 默认设置    字段宽度是容纳带打印数字所需的位数和小数点后打印 6 位数字

*3.852990e+03*        // 在小数点的左侧打印 1 个数字,在小数点的右侧打印 6 个数字

*3852.99*

*3853.0*        // 四舍五入

*  3852.990*

* 3.853E+03*        // 四舍五入        用 E 代替了 e

*+3852.99*        // 转换说明中包含了 + 标记

*0003852.99*        // 0 标记使得打印的值前面以 0 填充以满足字段要求

// 转换说明 %010.2f 的第1个0是标记,句点(.)之前、标记之后的数字(本例为10)是指定的字段宽度。

  • 演示一些格式标记
#include <stdio.h>
 
int main()
{
    printf("%x %X %#x\n", 31, 31, 31);
    printf("**%d**% d**% d**\n", 42, 42, -42);
    printf("**%5d**%5.3d**%05d**%05.3d**\n", 6, 6, 6, 6);
    return 0;
}

该程序的输出如下:

1f 1F 0x1f        // 1f 是十六进制数 等于十进制数 31

                       // 第1行printf()语句中 根据 %x 打印出1f     %F 打印出 1F     %#x打印出 0x1f

**42** 42**-42**        // 负值前面不产生前导空格

**     6**  006**00006**  006**        // 如果 0 标记和精度一起出现,0 标记会被忽略

  • 字符串格式
#include <stdio.h>
#define BLURB "Authentic imitation!"
 
int main()
{
    printf("[%2s]\n", BLURB);
    printf("[%24s]\n", BLURB);
    printf("[%24.5s]\n", BLURB);
    printf("[%-24.5s]\n", BLURB);
    return 0;
}

该程序的输出如下:

[Authentic imitation!]

[    Authentic imitation!]

[                   Authe]        // .5告诉 printf() 只打印 5 个字符

[                  Authe ]

四、使用scanf()函数

如果用 scanf() 读取基本变量类型的值,在变量名前加上一个 &

如果用 scanf() 把字符串读入字符数组中,不要使用 &

       scanf() 函数使用空白(换行符、制表符和空格)把输入分成多个字段。在依次把转换说明和字段匹配时跳过空白。

唯一例外的是 %c 转换说明。根据 %c scanf() 会读取每个字符,包括空白。

scanf() 的转换说明:

scanf()转换说明中的修饰符

1.scanf()角度看输入

scanf() 函数每次读取一个字符,跳过所有的空白字符,直至遇到第1 个非空白字符才开始读取。

       如果使用 %s 转换说明, scanf() 会读取除空白以外的所有字符。scanf() 跳过空白开始读取第 1 个非空白字符,并保存非空白字符直到再次遇到空白。

       C 语言还有其他的输入函数, 如 getchar() fgets() 这两个函数更适合处理一些特殊情况,如读取单个字符或包含空格的字符串。后面将会详细介绍。

2.格式字符串中的普通字符

       scanf() 函数允许把普通字符放在格式字符串中。除空格字符外的普通字符必须与输入字符串严格匹配。

例如,假设在两个转换说明中添加一个逗号

scanf("%d,%d", &n, &m);

       scanf() 函数将其解释成:用户将输入一个数字、一个逗号,然后再输入一个数字。也就是说,用户必须像下面这样进行输入两个整数:

88,121

       由于格式字符串中,%d 后面紧跟逗号,所以必须在输入 88 后再输入一个逗号。但是,由于scanf() 会跳过整数前面的空白,所以下面两种输入方式都可以:

88, 121

88,

121

格式字符串中的空白意味着跳过下一个输入项前面的所有空白。例如,对于下面的语句:

scanf("%d ,%d", &n, &m);

以下的输入格式都没问题:

88,121

88 ,121

88 , 121

请注意, 所有空白 的概念包括没有空格的特殊情况

       除了 %c ,其他转换说明都会自动跳过待输入值前面所有的空白。

       因此,scanf("%d%d", &n, &m) 与 scanf("%d %d", &n, &m) 的行为相同。对于 %c ,在格式字符串中添加一个空格字符会有所不同。例如,如果把 %c 放在格式字符串中的空格前面, scanf() 便会跳过空格,从第 1 个非 空白字符开始读取。也就是说, scanf("%c", &ch) 从输入中的第 1 个字符开始读取,而 scanf(" %c", &ch) 则从第 1 个非空白字符开始读取。

3.scanf()的返回值

       scanf() 函数返回成功读取的项数。如果没有读取任何项,且需要读取一个数字而用户却输入一个非数值字符串,scanf() 便返回 0 。当 scanf() 检测到 文件结尾 时,会返回 EOF EOF stdio.h 中定义的特殊值,通常用 #define 指令把 EOF 定义为 -1 )。

五、printf() 的用法提示

想把数据打印成列,指定固定字段宽度很有用。

       在两个转换说明中间插入一个空白字符,可以确保即使一个数字溢出了自己的字段,下一个数字也不会紧跟该数字一起输出(这样两个数字看起来像是一个数字)。这是因为格式字符串中的普通字符(包括空格)会被打印出来。


相关文章
|
1月前
|
存储 C语言
C语言数据类型、变量和运算符以及printf相关问题
C语言数据类型、变量和运算符以及printf相关问题
|
16天前
|
存储 C语言 数据格式
【C语言基础考研向】03混合运算和printf讲解
本文分为两部分。第一部分介绍了C语言中的混合运算与类型强制转换的重要性,通过实例展示了当整型数进行除法运算且结果为小数时,必须使用类型转换才能正确存储浮点数结果。第二部分详细讲解了`printf`函数的功能与使用方法,包括格式化输出不同类型数据的基本语法,并通过具体示例演示了如何利用字段宽度和对齐方式来控制输出格式,帮助读者更好地理解和掌握输出格式的控制技巧。
26 10
|
16天前
|
C语言
【C语言基础考研向】05 scanf读取标准输入超详解
本文详细解析了C语言中`scanf`函数的工作原理及常见问题。首先介绍了`scanf`如何处理标准输入,并通过示例说明了为何有时会出现阻塞现象及其解决办法。接着探讨了当输入包含多种数据类型时,特别是字符型数据的处理方式,强调了格式控制的重要性,并给出了正确的输入格式示例。通过正确配置,可以避免因空格和换行符导致的问题,确保数据准确读取。
29 10
|
16天前
|
存储 C语言
【C语言基础考研向】10 字符数组初始化及传递和scanf 读取字符串
本文介绍了C语言中字符数组的初始化方法及其在函数间传递的注意事项。字符数组初始化有两种方式:逐个字符赋值或整体初始化字符串。实际工作中常用后者,如`char c[10]=&quot;hello&quot;`。示例代码展示了如何初始化及传递字符数组,并解释了为何未正确添加结束符`\0`会导致乱码。此外,还讨论了`scanf`函数读取字符串时忽略空格和回车的特点。
|
19天前
|
C语言
C语言程序设计核心详解 第三章:顺序结构,printf(),scanf()详解
本章介绍顺序结构的基本框架及C语言的标准输入输出。程序从`main()`开始依次执行,框架包括输入、计算和输出三部分。重点讲解了`printf()`与`scanf()`函数:`printf()`用于格式化输出,支持多种占位符;`scanf()`用于格式化输入,需注意普通字符与占位符的区别。此外还介绍了`putchar()`和`getchar()`函数,分别用于输出和接收单个字符。
|
1月前
|
存储 缓存 编译器
【C语言篇】scanf和printf万字超详细介绍(基本加拓展用法)(下篇)
scanf处理⽤⼾输⼊的原理是,⽤⼾的输⼊先放⼊缓存,等到按下回⻋键后,按照占位符对缓存进⾏解读。 解读⽤⼾输⼊时,会从上⼀次解读遗留的第⼀个字符开始,直到读完缓存,或者遇到第⼀个不符合条件的字符为⽌。
|
1月前
|
存储 C语言
【C语言篇】scanf和printf万字超详细介绍(基本加拓展用法)(上篇)
printf 的作⽤是将参数⽂本输出到屏幕。它名字⾥⾯的 f 代表 format (格式化),表⽰可以定制输出⽂本的格式。
|
1月前
|
存储 安全 编译器
C语言中的scanf函数
C语言中的scanf函数
|
3月前
|
存储 C语言
c语言scanf函数用法
c语言scanf函数用法
|
3月前
|
存储 C语言
C语言中的printf函数详解
C语言中的printf函数详解