写点什么

玩转 C 语言:深入理解输入输出函数的奥秘

  • 2024-02-22
    福建
  • 本文字数:4207 字

    阅读完需:约 14 分钟

1. 单字符输出函数


在 C 语言中有一个函数 putchar 专门负责输出单个字符,其语法如下:


  1. 头文件:#include<stdio.h>

  2. 声明:int putchar(int char)

    char -- 这是要被写入的字符。该字符以其对应的 int 值进行传递。

  3. 作用:把参数 char 指定的字符(一个无符号字符)写入到标准输出 stdout 中,也就是输出单个字符。

  4. 返回值:该函数以无符号 char 强制转换为 int 的形式返回写入的字符,如果发生错误则返回 EOF。


以下是对 putchar 的具体使用示例:


#include<stdio.h>int main(){	putchar('A');//输出字符A		putchar('1');//输出字符1	putchar('\106');//输出转义字符F	return 0;}
复制代码


输出结果:



2. 多字符输出函数


既然有单字符输出函数,那就自然有多字符输出函数——puts,其语法如下:


  1. 头文件:#include<stdio.h>

  2. 声明:int puts(const char *str)str -- 这是要被写入的 C 字符串。

  3. 作用:把一个字符串写入到标准输出 stdout,直到空字符,但不包括空字符。换行符会被追加到输出中。

  4. 返回值:如果成功,该函数返回一个非负值为字符串长度(包括末尾的 \0),如果发生错误则返回 EOF。


以下是对 puts 的具体使用示例:


int main(){	puts("hello world\n");	puts("贝蒂来啦\n");	return 0;}
复制代码


输出结果:



3. 格式化输出函数

3.1 语法


介绍完单字符与多字符输出函数,下面我们将介绍格式化输出函数——printf,其语法如下:


  1. 头文件:#include<stdio.h>

  2. 声明:int printf(const char *format, ...)format -- 这是字符串,包含了要被写入到标准输出 stdout 的文本。它可以包含嵌入的 format 标签,format 标签可被随后的附加参数中指定的值替换,并按需求进行格式化。

  3. 作用:将参数⽂本输出到屏幕

  4. 返回值:如果成功,则返回写入的字符总数,否则返回一个负数。


3.2 占位符


printf() 可以在输出⽂本中指定占位符。所谓“占位符”,就是这个位置可以⽤其他值代⼊。下表是常见的占位符:



以下是对 printf 的具体使用示例:


int main(){	printf("%d\n", 5);//打印整型	printf("%f\n", 5.1);//打印浮点型	printf("%c\n", 'a');//打印字符	printf("%s\n", "betty");//打印字符串	printf("betty");//也可以这样打印字符串	return 0;}
复制代码


输出结果:



  • printf() 参数与占位符是⼀⼀对应关系,如果有 n 个占位符, printf() 的参数就应该有 n +1 个(双引号内部也算一个)。如果参数个数少于对应的占位符, printf() 可能会输出内存中的任意值。


3.3 限定格式


(1) 限定宽度


printf() 允许限定占位符的最⼩宽度。以下是具体的实例:


int main(){	printf("%4d\n", 123);	printf("%-4d\n", 123);	printf("%12f\n", 123.45);	return 0;}
复制代码



  • 上⾯⽰例中, %4d 表⽰这个占位符的宽度至少为 4 位。如果不满 4 位,对应的值的前⾯会添加空格。输出的值默认是右对⻬,即输出内容前⾯会有空格;如果希望改成左对⻬,在输出内容后⾯添加空格,可以在占位符的 % 的后⾯插⼊⼀个 - 号。

  • 对于⼩数,这个限定符会限制所有数字的最⼩显⽰宽度。上⾯⽰例中, %12f 表⽰输出的浮点数最少要占据 12 位。由于⼩数的默认显⽰精度是⼩数点后 6 位,所以 123.45 输出结果的头部会添加 2 个空格。


(2) 总是显示正负号


默认情况下, printf() 不对正数显示 + 号,只对负数显示 - 号。如果想让正数也输出 + 号,可以在占位符的 % 后⾯加⼀个 + 。


int main(){	printf("%+d\n", 13);	printf("%+d\n", -13);	return 0;}
复制代码


(3) 限制小数位数


输出⼩数时,有时希望限定⼩数的位数。举例来说,希望⼩数点后⾯只保留两位,占位符可以写成 %.2f 。


#include <stdio.h>int main(){	printf("Number is %.2f\n", 0.5);//输出0.50	return 0;}
复制代码


  • 这种写法也是可以与限定宽度结合使用的


(4) 限定字符串的输出


%s 占位符⽤来输出字符串,默认是全部输出。如果只想输出开头的部分,可以⽤ %.[m]s 指定输出的⻓度,其中 [m] 代表⼀个数字,表⽰所要输出的⻓度。


#include <stdio.h>int main(){	printf("%.5s", "hello world");	return 0;}
复制代码


输出结果:



(5) 限定值输入


最⼩宽度和⼩数位数这两个限定值,都可以⽤ ***** 代替,通过 printf() 的参数传⼊。


#include <stdio.h>int main(){    printf("%*.*f\n", 6, 2, 0.5);    return 0;}// 等同于printf("%6.2f\n", 0.5);
复制代码


3.4 printf 的返回值


我们在前面介绍 printf 时候就已经了解过其返回值:如果成功,则返回写入的字符总数,否则返回一个负数。

下面就让我们通过下列两道题来加深理解:

(1) 题目一


int main(){	int a = 43;	printf("%d\n", printf("%d", printf("%d", a)));//输出什么??	return 0;}
复制代码


  1. 首先肯定会执行最里面的 printf("%d",43),在屏幕上打印出 43。

  2. 然后执行 printf("%d", printf("%d", 43)),相当于打印第一步 printf 的返回值,‘4’,‘3’有两个字符,所以返回值是 2。

  3. 最后同理执行 printf("%d", printf("%d", printf("%d", 43))),即打印第二步的‘2’返回值,一个字符,返回值为 1。

  4. 所以屏幕上最后打印的就是 4321



(2) 题目二


int main(){    printf("%d\n",printf("%d\n",printf("hello!\n"))); //输出??    return 0;}https://s11.ax1x.com/2024/02/20/pFYxXCT.png
复制代码


  1. 首先肯定会打印出 hello!然后换行。

  2. 然后打印 printf("%d\n",printf("hello!\n")),即第一步的返回值,需要注意是‘\n’是一个字符,所以返回值是 7,换行。

  3. 最后打印 printf("%d\n",printf("%d\n",printf("hello!\n"))),即第二步的返回值,格式化字符串的‘\n’也会算做一个字符,一共两个字符,所以最后打印出 2。



4. 单字符输入函数


单字符输入函数——getchar,顾名思义就是读取一个字符,其用法如下:


  1. 头文件:#include<stdio.h>

  2. 声明:int getchar()

  3. 作用:从标准输入 stdin 获取一个字符(一个无符号字符)

  4. 返回值:该函数以无符号 char 强制转换为 int 的形式返回读取的字符,如果到达文件末尾或发生读错误,则返回 EOF。


下面的实例演示了 getchar() 函数的用法:


#include <stdio.h>
int main(){ char c; printf("请输入字符:"); c = getchar(); printf("输入的字符:"); putchar(c); return 0 ;}
复制代码


输出结果:



5. 多字符输入函数


多字符输入函数——gets,顾名思义就是输入一个字符,其用法如下:


  1. 头文件:#include<stdio.h>

  2. 声明:char *gets(char *str)str -- 这是指向一个字符数组的指针,该数组存储了 C 字符串。

  3. 作用:从标准输入 stdin 读取一行,并把它存储在 str 所指向的字符串中。

  4. 返回值:如果成功,该函数返回 str。如果发生错误或者到达文件末尾时还未读取任何字符,则返回 NULL。


下面的实例演示了 gets() 函数的用法:


#include <stdio.h>int main(){	char str[20] = { 0 };	printf("请输入一个字符串:");	gets(str);	printf("您输入的字符串是:%s", str);	return(0);}
复制代码


输出结果:



6. 格式化输入函数

6.1 语法


下列是格式化输入函数——scanf 的用法:


  1. 头文件:#include<stdio.h>

  2. 声明:int scanf(const char *format, ...)format -- 这是 C 字符串,包含了以下各项中的一个或多个:空格字符、非空格字符和 format 说明符。

  3. 作用: 从标准输入 stdin 读取格式化输入

  4. 返回值:如果成功,该函数返回成功匹配和赋值的个数。如果到达文件末尾或发生读错误,则返回 EOF。


下面的实例演示了 scanf() 函数的用法:


#include<stdio.h>int main(){    int a, b, c;    printf("请输入三个数字:");    scanf("%d%d%d", &a, &b, &c);    printf("输出结果是:%d,%d,%d\n", a, b, c);    return 0;}
复制代码


  • &a、&b、&c 中的 & 是地址运算符,分别获得这三个变量的内存地址。

  • %d%d%d 是按十进值格式输入三个数值。输入时,在两个数据之间可以用一个或多个空格、tab 键、回车键分隔。


输出结果:



  • 并且输入数据也要与格式化内数据保持一致。什么意思呢?我们以下面这段代码举例说明:


#include<stdio.h>int main(){    int a, b;    scanf("%d,d", &a, &b);    //输入a,b?    //输入a b?    printf("输出结果是:%d,%d\n", a, b, );    return 0;}
复制代码


  • 上诉代码只能输入 a,b,而不能输入 a b 因为要与格式化内容相匹配。

6.2 scanf 与 gets 之间的区别


scanf 在处理占位符时候,如果占位符不是 %c,会忽略起始的空格(非起始的空格会停止),换行符,制表符。而 gets 可以将输入流的数据全部读取。比如说下面这段代码:


#include<stdio.h>//如果输入hello betty//分别输出什么int main(){    char arr1[20];//存放字符串    gets(arr1);    char arr2[20];//存放字符串    scanf("%s ", arr2);    printf("arr1输出:%s\n",arr1);    printf("arr2输出:%s\n", arr2);    return 0;}
复制代码



  • 第一次输入 gets 全部读取,第二次输入 printf 遇见空格就停止读取。

6.3 缓存区


scanf() 处理用户输⼊的原理是,用户的输⼊先放⼊一个区域,等到按下回⻋键后,按照占位符对缓存进⾏解读。而这个区域就是我们的缓存区



注:标准输入⼀般指的就是键盘,标准输出⼀般指的就是屏幕


知道了缓冲区之后,让我们来分析一段代码:


int main(){	char password[20];	printf("请输入你的密码:");        scanf("%s", password);	int ret = getchar();	printf("请再次确认你的密码(Y/N):");	if (ret == 'Y')	{		printf("密码正确\n");	}	else	{		printf("密码错误\n");	}	return 0;}
复制代码


输出结果:



为什么会出现这样的结果呢?这时就要运用缓冲区的知识,在我们输入 abc 回车(\n)时,缓冲区中的数据为 abc\n,而 scanf 只会读取 abc,\n 会被一直留在缓冲区。所以在 getchar 再次读取时会自动读取\n,输出密码错误。


解决这个问题也很简单,我们只需要再加一个 getchar 提前把\n 读取就行了。


int main(){	char password[20];	printf("请输入你的密码:");	scanf("%s", password);	printf("请再次确认你的密码(Y/N):");	getchar();//清空缓冲区	int ret = getchar();	if (ret == 'Y')	{		printf("密码正确\n");	}	else	{		printf("密码错误\n");
} return 0;}
复制代码


6.4 scanf 的返回值

如果成功,该函数返回成功匹配和赋值的个数。如果到达文件末尾或发生读错误,则返回 EOF。这一点常常用于多组数据输入,比如说多组数据求和,可以写成如下形式:


int main(){	int a, b;	while (scanf("%d%d") == 2)	{		int sum = a + b;		printf("%d", sum);	}	return 0;}
复制代码


  • 在 VS 环境下可以按 3 次 ctrl+z 强制结束。


文章转载自:Betty’sSweet

原文链接:https://www.cnblogs.com/bett/p/18024951

体验地址:http://www.jnpfsoft.com/?from=001

用户头像

还未添加个人签名 2023-06-19 加入

还未添加个人简介

评论

发布
暂无评论
玩转C语言:深入理解输入输出函数的奥秘_算法_快乐非自愿限量之名_InfoQ写作社区