C语言详解-输入输出

article/2025/10/30 23:51:05

1. 输入输出一览

以下输入输出库函数的操作主要在标准输入输出设备(键盘和屏幕)与数据缓冲区之间进行。

1.1 printf()与scanf ()

printf(): 将指定的文字/字符串输出到标准输出设备(屏幕)。
注意宽度输出和精度输出控制

scanf(): 从标准输入设备(键盘)读取数据,并将值存放在变量中。

1、格式说明符个数与输入数据个数不相等的情况:
当我们从键盘输入数据时,数据之间必须用分隔符分开(空格、Tab键、回车)。并且要求scanf函数中格式说明符的个数与数据列表中数据的个数相等。如:

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

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

如果出现不相等的情况,我们应该怎么分析呢?

其实,当我们输入数据时,只要没有按回车键,所输入的数据都还存放在缓冲区,并没有存入变量中。按【Enter】键后,scanf()函数才会从缓冲区中取走数据。缓冲区是一个先进先出的队列,即取走数据的时候,遵循先输入的数据先取走的原则。scanf函数的格式说明符有几个就要取几次数据,只要碰到格式说明符就必须把数据取走,至于是不是要把取走的数据存放起来,就得看数据列表中的数据个数。没取完的数据继续留在缓冲区中

以下是缓冲区示意图,它像一根管道,有一个入口和一个出口,数据只能从入口中存入,只能从出口中取出。

在这里插入图片描述
以下是针对该图的C程序,数据输入为:10<空格>20<空格>30<空格>40<回车>

/**输入数据格式:10<空格>20<空格>30<空格>40<回车>*输出:a=10 b=20c=30*/#include <stdio.h>int main()
{	int a, b, c;scanf("%d%d", &a, &b); /* scanf中有2个格式说明符,  表明要取两次数据,取走10和20缓冲区中还剩下30和40*/printf("a=%d b=%d \n", a, b);scanf("%d", &c); /* scanf中只有1个格式说明符,表明要取1次数据,取走30缓冲区中还剩下40,因此,读者还可以取一次。。。。。*/printf("c=%d \n", c);return 0;
}

输出效果:
在这里插入图片描述
2、宽度输出的情况:

(1) 在%和格式字符之间加入一个整数来控制输出数据所占宽度
printf("%d\n", 365);
printf("%2d\n", 365);
printf("%5d\n", 365);
printf("%f\n", 3.14);
printf("%6f\n", 3.14);
printf("%12f\n", 3.14);

输出效果:
在这里插入图片描述
规则:

  1. 当宽度小于数据的实际宽度时,按照实际数据宽度输出;当宽度大于数据的实际宽度时,在数据的左边添加空格补齐宽度,一个空格相当于一个宽度。
  2. 浮点数格式说明符%f输出时,默认保留六位小数

(2) 在%和格式字符f之间加入一个“整数1. 整数2”来控制输出数据的格式
整数1:整个输出数据占的总宽度
整数2:输出实数的小数部分的个数
记住:先用整数2处理小数部分,再用整数1处理整个数据,包括已处理好的小数部分

printf("%3.3f\n", 3.1415);
printf("%3.5f\n", 3.1415);
printf("%9.5f\n", 3.1415);
printf("%9.0f\n", 3.1415);

输出效果:
在这里插入图片描述
3、宽度输入的情况:

宽度输入指的是在%和格式说明符d之间加入一个整数。如:scanf("%2d", &x);

规则:

  1. 注意:%d与%1d是不同的
  2. 先根据格式说明符截取符合格式说明符的部分作为一个数放入缓冲区,再将剩余部分作为另一个数放入缓冲区。
  3. 当宽度小于数据的实际宽度时,截取指定宽度的部分作为一个数进入缓冲区,再将剩余部分作为另一个数放入缓冲区;当宽度大于数据的实际宽度时,把实际数据放入缓冲区。
    记住:小于1的小数输入可以直接忽略零,从小数点位开始输入。

基于以下程序进行测试,测试结果如下:

#include <stdio.h>main()
{int a;float b,c;scanf("%3d%f%f",&a,&b,&c);printf("%d %f %f \n", a, b, c);
}

test case #1:
输入:1<空格>2<空格>3<回车>
输出:1 2.000000 3.000000

test case #2:
输入:123<空格>4<空格>5.1234567<回车>
输出:123 4.000000 5.123456

test case #3:
输入:1234<空格>5<空格>6<回车>
输出:123 4.000000 5.000000

test case #4:
输入:1.23<空格>4<空格>5<回车>
输出:1 0.230000 4.000000

test case #5:
输入:123.45<空格>6<空格>7<回车>
输出:123 0.450000 6.000000

test case #6:
输入:1234.5<空格>6<空格>7<回车>
输出:123 4.500000 6.000000

*4、scanf中的%[^]%c格式

规则:

  1. scanf的格式控制的一般形式为:%[*][宽度][F|N][h|l]类型字符[]中的控制字符为可选项
  2. "*"表示该输入项读入后不赋予任何变量,即跳过该输入值。
  3. “%n[a-z]” 读入最多n个字符,如果遇到非a-z的字符,停止
  4. “%[^=]” 读入任意多的字符,直到遇到"="停止
  5. “%n[^=]” 读入"="号前的至多n 个字符
  6. ^表示"非",即读入其后面的字符就结束读入
  7. 所有对%s起作用的控制都可以用%[],比如%[0-9]表示只读入’0’到’9’之间的字符,%[a-zA-Z]表示只读入字母,’-'是范围连接符,当然也可以直接列出你需要读入的字符。

1.2 getchar()与putchar()

getchar(): 将用户输入的字符输出到标准输出设备(屏幕)。按【Enter】键后,getchar()函数才会读入第一个字符,并返回该字符常量。

注:由于缓冲区的读取特性,当用户由键盘键入字符时,计算机并不会马上处理,而会暂存到系统的缓冲区(Buffter)内。到按【Enter】键后,getchar()函数才会读入缓冲区的第一个字符。而其它字符继续保留在缓冲区,等待下一个读取字符/字符串的函数来读入。

putchar(): 用来输出指定的单一字符。

例1. 运行以下程序,输入:Hello!<回车>

#include <stdio.h>int main()
{	char c, s[20];printf("Enter a string: ");c = getchar();printf("Read the remaining from the buffer\n");scanf("%s", s);putchar(c);putchar('\n');printf("%s \n", s);
}

输出效果:

在这里插入图片描述
例2. 输入一个汉字,并将它显示在屏幕上。
先输入:B超<回车>,观察输出。再运行程序,输入:超<回车>,比较输出结果:

#include <stdio.h>int main()
{char c1, c2;printf("Enter an Chinese character: ");c1 = getchar();c2 = getchar();printf("The Chinese character entered is: ");putchar(c1);putchar(c2);putchar('\n');
}

第一次运行结果:
在这里插入图片描述
第二次运行结果:
在这里插入图片描述
**注:**由对比可知,当输入第一个数据时,只输出了字母“B”,汉字“超”没有输出。原因是一个汉字需要两个字节(字符)才能表示,所以对于第一个输入而言,所输入的字符“超”的第二个字节内容仍然保留在缓冲区。第二次运行,只输入“超”字时,通过两个getchar()函数将缓冲区中的“超”字全部读出,并用两次putchar()显示了一个完整的汉字。

1.3 getche()与getch()

getche(): 该函数会由键盘输入一个字符,返回给调用者,并在屏幕上显示读入的字符。由于它并不读取缓冲区的字符,只要用户输入字符,getche()函数会立刻读取,而不需等待按【Enter】键。通常用于程序中只需用户输入一个字符,即可往下继续执行的情形。
getch(): 它与getche()的区别是,getch()不需将所输入的字符显示到屏幕上。

例3. 测试getche()和getch()

#include <stdio.h>#include <conio.h> /* getche(), getch() */int main()
{char c1, c2;printf("Press any key to exit");c1 = getche();putchar('\n');printf("Press any key once more to exit");c2 = getch();putchar('\n');printf("The character getche() read: %c \n", c1);printf("The character getch() read: %c \n", c2);
}

输出效果:
在这里插入图片描述

1.4 gets()与puts()

gets():

==scanf输入字符串可以配合%s格式,但缺点是当遇到字符串中有空白或tab字符时,会自动视为串输入结束。==因此不适合输入包含空白/tab字符的字符串。这时gets()函数就可解决该问题。

gets()函数会将用户整段字符串响应到标准输出设备(屏幕)上,当用户按下【Enter】键时,会读取缓冲区的所有字符并存放到指定字符数组中。

比较适合应用在多字符,中文字或长字符串的读取。

puts(): 用来输出字符串输出完成后光标自动移到下一行。当输出数据时,会以’\0’字符作为该字符串的结束

例4. 测试gets()和puts()

#include <stdio.h>int main()
{char s[50];printf("Enter a string: "); gets(s);printf("The string you entered: ");    puts(s); 
}

在这里插入图片描述

2. stdio.h文件

另外还有一组输入输出函数是getc()和putc(),它们的作用也是输入和输出一个字符,先看它们在头文件stdio.h中的定义。

以下是头文件stdio.h的部分内容,请注意注释部分:

#define EOF  (-1) //EOF的定义/* NULL指针值的定义 */
#ifndef NULL
#ifdef  __cplusplus
#define NULL    0
#else
#define NULL    ((void *)0)
#endif
#endif/* 标准I/O设备数组_iob[]的定义 */
#ifndef _STDIO_DEFINED
_CRTIMP extern FILE _iob[];
#endif /* 标准I/O设备的定义 */
#define stdin  (&_iob[0])
#define stdout (&_iob[1])
#define stderr (&_iob[2])/* 函数原型 */
_CRTIMP int __cdecl getc(FILE *);
_CRTIMP int __cdecl putc(int, FILE *);/* 宏定义 */
#define getchar()         getc(stdin) //调用getchar()时,实际调用的是getc(stdin)
#define putchar(_c)       putc((_c),stdout) //调用putchar(_c)时,实际调用的是putc((_c), stdin)

例5. getc()函数和putc()函数

#include <stdio.h>void main()
{int ch;FILE *pfin = stdin; //定义一个文件指针,并指向标准输入设备(键盘)FILE *pfout = stdout; //定义一个文件指针,并指向标准输出设备(屏幕)printf("Enter a string: ");ch = getc(pfin); //使用getc()函数获取缓冲区中的第一个字符putc(ch, pfout); //使用putc()函数输出该字符putc('\n', pfout); //使用putc()函数输出换行字符
}

运行结果:
Enter a string: Testing!
T
Press any key to continue


http://chatgpt.dhexx.cn/article/g8fO2Tst.shtml

相关文章

None、Null与空字符‘‘什么区别

1. None 表示空无一物&#xff0c;啥也没有存储。 编程语言里采用None 比如在python中None不是一个保留关键字&#xff0c;只是NoneType对象的一个实例。 空就是空&#xff0c;它不是整型&#xff0c;不是浮点型&#xff0c;也不是字符串&#xff0c;就是一个NoneType。所以在…

关于“空”string字符串

string a ""; string b ""; string c string.Empty; string d string.Empty; string e null; string f null;等运行完后在即时窗口中用&命令查看这些变量的地址 然后发现&#xff0c;所有变量的栈地址都不同&#xff08;废话&#xff09;&#x…

空字符串、NULL、空格串的区别

1、表示区别 string str1 ""; //空字符串 str1.length() 等于 0 string str2 null; //NULL string str3 " "; //空格串 str2.length() 等于 1 2、内存区别 "" &#xff1a;分配了内存 &#xff0c;分配了一个空间 null…

如何输入带空格的字符串

转载自&#xff1a;https://www.cnblogs.com/houchen/p/10356396.html 问题一&#xff1a;带空格的字符串输入(c) 对于string类 getline(cin, str) 对于字符数组 方法一&#xff1a;getline() 读入整行数据&#xff0c;使用回车键输入的换行符来确定输入结尾。 调用方法&am…

C++ 空字符

C 空字符 本来想定义一个空的字符&#xff0c;想当然的就写成了下面的样子&#xff1a; #include <iostream>using namespace std; int main() {char ch ;cout<<ch<<endl;return 0; } 运行直接报错 加上\0 就对了 &#xff0c; 哎 基础呀。。。。。 #i…

【Java】Java中空字符的写法

首先要明确空字符和空格字符的区别 空字符表示数据为空&#xff1b; 空格字符表示数据不为空&#xff0c;为一个空格字符。 Java和C中使用\0表示空字符&#xff0c;Python使用表示空字符。 public class Test {public static void main(String[] args) {char s[] new char[…

MySQL中的空值 Null 和空字符‘‘

目录 1. 空值 Null 和空字符 2. 空值 Null 和空字符 在查询方式上的对比2.1. 创建 SQL 脚本2.2. 查询 username 列为空字符串 的所有数据2.3. 查询 username 列为空值 null 的所有数据2.3.1. 错误 SQL2.3.2. 正确 SQL 2.4. 查询 username 列不为空值 null 的所有数据2.4.1. 错…

空字符'\0'与字符串

from&#xff1a; https://blog.csdn.net/bairenxinmo/article/details/17662983 空字符\0 空字符即NUL字节&#xff0c;是一个ASCII值为0的控制字符&#xff0c;在程序代码中通常以转义序列\0表示&#xff0c;在C语言中&#xff0c;空字符非常重要&#xff0c;主要体现在字符…

空字符和空格字符有什么区别?

char ch1 \0 ,ch2 ;System.out.println(""(int)ch1);System.out.println(""(int)ch2); 运行结果 由此可见&#xff0c;空字符(\0)的ascii值是0&#xff0c;实际应用上是字符串结尾自动补上的一个字符 有的时候用来判断是否到了字符串结尾 而空格字符…

认真理清 一一空字符('\0')、空指针(NULL)、\0、0

在C/C语言中我们经常看到’\0’、NULL。从概念上看两者完全不同&#xff0c;但是本质上他们都可以用数值0来表示。空指针是指针类型&#xff0c;而空字符是整形类型&#xff0c;两者有时很容易混淆。 NULL 空指针有一个值&#xff0c;该值不会与任何数据的有效值地址对应。通…

空字符 空格字符(字符) 空字符串 NULL的区别

【1】 空字符 空格字符&#xff08;字符&#xff09;【2】空字符串 【3】 NULL的区别 1.1 字符 &#xff08;1&#xff09;首先必须明确字符型&#xff08;char&#xff09;是整数类型&#xff0c;其在内存单元是以整数形式存放。 &#xff08;2&#xff09;其次&am…

CSS属性值的计算过程

属性值的计算过程 一个元素一个元素依次渲染&#xff0c;顺序按照页面文档的树形目录结构进行 渲染每个元素的前提条件&#xff1a;该元素的所有CSS属性必须有值 一个元素&#xff0c;从所有属性都没有值&#xff0c;到所有的属性都有值&#xff0c;这个计算过程&#xff0…

Java 反射设置/获取对象属性值

✨大家好&#xff0c;我是【zhuzicc】~ &#xff0c;一位主攻【Java】的 攻城狮&#xff01;✨ 欢迎对【Java】感兴趣的大佬&#xff0c;关注我 &#x1f61c; ———————————————— ❤️ ❤️ ❤️ 如果觉得本文还不错&#xff0c;点赞 评论 关注 收藏。有补充…

字段与属性

字段的使用: 1.关于字段 a.字段又称为&#xff1a;“成员变量”&#xff0c;一般在类的内部做数据交互使用。 b.字段命名规范&#xff1a;camel命名法&#xff08;Camel 命名法是指第一个单词小写&#xff0c;从第二个单词开始每个单词的首字母大写&#xff09;。 2.通俗的理解…

jQuery获取标签属性值(一)

1、box-shadow属性可以设置盒子阴影的效果其参数为&#xff1a; box-shadow: h-shadow v-shadow blur spread color inset; h-shadow必需的。水平阴影的位置。允许负值v-shadow必需的。垂直阴影的位置。允许负值blur可选。模糊距离spread可选。阴影的大小color可选。阴影的颜…

如何获取对象的属性及属性值

for(key in attr){//key:属性名//attr[key]:属性值 } 转载于:https://www.cnblogs.com/wanlibingfeng/p/10070080.html

JS中如何通过属性获取属性值

JS中如何通过属性获取属性值 const mySymbol Symbol()let obj {name:cwl,1: 1,true:bool,[mySymbol]: sym, }当属性名是字符串 一般通过 . 来访问 obj.name当属性名是数字时 obj[1] //√ obj.1 //报错当属性值是bool类型 obj[true] obj.true obj[true]当属性值为Symbol类…

获取object对象中的属性值

获取object对象中的属性值 先创建一个实体类并向上转型为Object类 假设实体类如下 public class WordDto {private String uuId;private Long id;private Long aid;private String content;}WordDto dtonew WordDto();dto.setAid(10000002L).setId(12L).setUuId("12345…

值类型属性??

再一次由于C#中值类型和引用类型的区别 犯了错误。 假设在类中包含一些值类型的成员&#xff08;比如结构&#xff0c;数组&#xff09;&#xff0c;你希望为外部程序提供访问和修改这些成员的能力&#xff0c;同时又不想直接暴露成员&#xff0c;在c#中最常见的做法就…