概要

在C语言中,往往常用到字符串、数组等,对于一个字符串,其输入很简单,一个语句即可完成,而对于整型数组,我们常遇到的情况都是已知数组长度,即元素的个数之后,用一个for循环完成输入。

然而,如果事先不知道需要输入元素的个数,要求从键盘输入多少个整数便记录多少个,回车之后即完成输入,对于这个问题,看似简单,但对于初学者来说,似乎一时还真没有思路。

长度未定的整型数组

1、关于scanf()

sacnf() 是C语言标准库中的输入函数,功能是从标准输入 stdin 读取格式化输入,其一般形式为:

scanf(格式控制,地址列表)

格式控制部分是一个字符串,其中格式声明以 '%' 开始,以一个格式字符结束,中间可以插入附加字符,表示属性。除此之外,还可以含有其他的字符(空格字符、转义字符中的字符和非空格的普通字符),但需要注意的是,如果格式控制字符串中除了格式声明,还含有其他的普通字符,那么在输入时应该在对应位置输入相同字符,不能改写也不能漏写,因为系统是逐个对照检查的。

此外,之所以把空格字符和转义字符中的字符(如Enter、Tab)单独列出来,是基于其特殊之处:

(1).在使用 '%f' 、'%d' 作为格式声明进行数值的输入时,转义字符和空格是作为无效字符,仅仅是作为一个数值与另一个数值中间分隔的作用,或者说是作为一个数值的输入结束标志。

说着都是苍白的,“No photo you say a J8”。

示例1:在格式控制中,格式声明之间没有普通字符的

scanf("%d%d", &A, &B);

对于这种情形,必须在 一个数值输入完成后加一个结束标志作为分隔,可以是空格、回车、Tab。

输入1:520[空格]250↵

输入2:520[Tab]250↵

输入3:530↵250↵

输入4:520[空格][Tab]↵↵250↵

对于上述4组不同的输入方式,结果如下:

表1-不同输入下结果对比

可见,在进行数值输入时,如果格式控制字符串中没有其他普通字符,空格、回车和Tab等仅仅在格式声明之间起分隔作用,个数不限。

同理可以推测,在格式控制字符串中如果格式声明间除普通字符外,含有的空格、回车或Tab等可以忽略,也可以随便输多少个,也即对于这三个,只作为分隔作用。

 示例2:在格式字符串中,格式声明之间含有普通字符

scanf("%d/WNDMD/ /WRSNDM/%d", &A, &B);

该语句的格式控制字符串中一共有两个格式声明,中间有两段普通字符串,中间隔了一个空格。

由上文已知,在进行数值的输入时,空格、回车以及Tab的作用都是一样的,作为分隔,而且数目不限,所以,在以下测试中,就不再使用回车和Tab作为分隔,仅用空格就可以说明问题。此外,如果格式声明之间已经含有普通字符,那么就无需再加入分隔字符,也就是输入结束标志。

输入1:250/WNDMD/[空格]/WRSNDM/3600↵

输入2:250/WNDMD//WRSNDM/3600↵

输入3:250/WNDMD//WRSNDM/[空格]3600↵

输入4:250[空格]/WNDMD//WRSNDM/3600↵

结果如下:

表2-不同输入下结果对比

可见,图1-3都是正常的,图4出现了问题,图1即为一一对应输入,图2是去掉了两个普通字符串之间的空格,图3是在输入完普通字符后再加入了空格,即结束标志,其结果都是正确的,验证了上述结论。

而图4出现错误,是因为在输入第一个数值后系统本该直接开始检查 "/WDNMD/" 却出现了空格,所以第二个数值便不能正常输入。

可以推测,如果在格式控制字符串中第一个格式声明后加上一个空格,那么输入时,第一个数值后可以输入多个空格,也可以直接忽略掉,后面照上述输入1-3都行(因为格式控制字符串中,格式声明之间如果有普通字符,那么所有的结束标志都可以忽略)。

scanf("%d /WNDMD/ /WRSNDM/%d", &A, &B);

输入1:250[空格][空格][空格]/WNDMD//WRSNDM/3600↵

输入2:250/WNDMD//WRSNDM/3600↵

结果如下:

表3-不同输入下结果对比

各种情况都列了出来,其他的不必多言。

(2).在使用 '%c' 作为格式声明进行字符输入时,空格字符和转义字符中的字符都作为有效字符。

示例3:对这样一个输入语句

char A, B;
scanf("%c%c", &A, &B);

对于如下输入:

输入1:NB↵

输入2:N[空格]↵

输入3:↵[空格]↵

结果如下:

表4-不同输入下结果对比

结果明显和上文描述中的一致。

(3).在使用'%s'作为格式声明进行字符串输入时,回车作为一个字符串的输入结束标志,空格以及Tab都作为无效字符,起分隔作用。

示例4:对以下输入语句

char str[15];
scanf("%s",str);

对于以下输入:

Fu*k[空格]You[空格]Man! ↵

TFu*k[Tab]You[Tab]Man! ↵

结果如下:

表5-不同输入下结果对比

可通过如下语句输入多个字符串:

char str1[6], str2[6], str3[6];
scanf("%s%s%s", str1, str2, str3);

对于输入:

Fu*k[空格]You[空格]Man! ↵

TFu*k[Tab]You[Tab]Man! ↵

TFu*k↵You↵Man! ↵

有如下结果:

表6-不同输入下结果对比

结果一目了然。

2、具体实施

在整型数组元素个数不确定的情况下,输入了多少个整数便放多少个到数组中。

scanf()说到底就是从stdin中格式化地读取数据,而数据在stdin中的存放形式也是字符串,所以实现的原理很简单,先取出第一个,判断是否为十进制数,是的话就从取出来的那个开始按整形的格式读,直到遇到结束标志,由上文已经知道,空格、回车、Tab以及普通字符都可以作为数值输入的结束字符,所以会自动读取到下一个非十进制数的位置;如果取出的那个字符不是十进制数,那么继续取下一个。

如此,代码如下:

int main(void) {//长度未定的整形数组输入int Num[1000],Loc;char Temp;Loc = 0;//Loc表示已经输入[读取]的整形数的个数while ((Temp = getchar()) != '\n') {//从stdin流中获取第一个字符if (isdigit(Temp)) {//判断该字符是否为十进制数ungetc(Temp, stdin);//若是十进制数,则将改字符退回输入流scanf("%d", &Num[Loc++]);//开始从该字符处开始读取int型数}//如果不是十进制数,直接跳过,开始读下一个[读一个少一个]}return 0;
}

注释很清楚,无需多言。

补充

1、长度确定的整型数组的输入

//确定长度的整形数组输入
int Num[N];//此处N是个具体的数,不能是变量,这样写只是为了更好地展示
for (int i = 0; i < N; i++) {scanf("%d", &Num[i]);//输入时可使用逗号或者空格隔开,以回车键结束输入
}

2、字符的输入

char C;
//method 1
scanf("%c", &C);//method 2
C=getchar();

3、字符串的输入

char Str;
//method 1
scanf("%s",Str);//method 2
gets(Str);//method 3
int N;
gets_s(Str, N);//method 4
int N;
fgets(Str, N, stdin);

上述函数中,gets()、gets_s()和fgets有必要单独拿出来讲一下区别和用法,鉴于已经存在关于这个的总结得很优秀的文章,就不再赘述。

可参考:

(1条消息) gets,fgets,gets_s的区别分析_如果我开挖掘机你还爱我吗的博客-CSDN博客_gets_s函数和gets区别

C语言:输入一个长度未定的整形数组[C_001]相关推荐

  1. C语言 输入一个长度小于80的字符串,将字符串中的字母字符滤掉掉,并统计新生成串中包含的字符个数。

    C语言实现:输入一个长度小于80的字符串,修改此字符串,将字符串中的字母字符滤掉掉,并统计新生成串中包含的字符个数.主函数如下,请实现函数fun. 主函数代码: #include <stdio. ...

  2. c语言定义一个长度为6的数组,定义一个长度为6的数组,从键盘输入6个数据给数组,并显示;然后输出该数组中第三大的数据x....

    满意答案 rui0616 推荐于 2017.09.28 采纳率:45%    等级:8 已帮助:213人 我不知道你需要使用C还是C++,所以我偶是用了C++#include #include usi ...

  3. C语言输入一个任意数求各位数的和

    C语言输入一个任意数求各位数的和 int main(void) {int x, r, s = 0;scanf("%d", &x);while (x>0){r = x ...

  4. C语言 输入一个字符串,统计字符个数,并按照倒序输出该字符串。

    题目:C语言 输入一个字符串,统计字符个数,并按照倒序输出该字符串. #include<stdio.h>void main() {char str[10];scanf("%s&q ...

  5. C语言 输入一个5行5列的数组。1.求数组主对角线上元素的和。2.求出辅对角线上元素的积。3.找出主对角线上最大的值及其位置

    C语言 输入一个5行5列的数组.1.求数组主对角线上元素的和.2.求出辅对角线上元素的积.3.找出主对角线上最大的值及其位置 主对角线是什么: 在一个n阶方阵(或是n阶行列式)中,从左上角到右下角这一 ...

  6. C语言 输入一个数值,分析是正还是负,并打印出此数

    C语言  输入一个数值,分析是正还是负,并打印出此数 #include <stdio.h>int main(void) {int x;printf("张宝田\n");s ...

  7. C语言 输入一个字符,并判断这个字符属于哪一类字符

    C语言 输入一个字符,并判断这个字符属于哪一类字符. #include<stdio.h> int main () {char ch;ch = getchar();putchar(ch);i ...

  8. 输入一个长度不超过100的字符串,删除串中的重复字符。

    #include <stdio.h> #include <string.h> #define N 200 int main() { char a[N]; //存储字符串. in ...

  9. 偶数乘2奇数乘3C语言,输入一个整数x,如果为偶数乘2,否则乘3,然后输出.C语言

    编写一个程序,输入一个正整数,并做以下运算:如果为偶数,除以2,如果为奇数,乘3加1.得到的结果再按上 本人不会C#,算法相通,用c语言演示一下:#includevoidmain(void){intz ...

最新文章

  1. WMI技术介绍和应用——查询系统信息和补丁包信息
  2. wsdd文件是怎么生成的_Axis WSDD文件参考文档
  3. 医工汇聚 智竞心电 | 首届中国心电智能大赛开启招募
  4. 如何线程安全的使用HashMap
  5. C#在循环中使用Random时生成的随机数相同的解决办法
  6. php编写服务器端脚本程序,PHP脚本语言写的简单服务器程序
  7. win10系统卷影复制服务器,如何使用Windows卷影拷贝服务恢复文件和文件夹
  8. 最新 955 不加班公司名单
  9. SpringCloud项目:实现推送消息到RabbitMQ消息中间件
  10. pytorch ner
  11. 乐视 logo 换新:显示“老板造车美利坚”;雷军给米粉起名小粽子;谷歌浏览器不再隐藏完整 URL|极客头条...
  12. [置顶] Android代码-----检测手机耳机插拔
  13. Ubuntu菜鸟入门(五)—— 一些编程相关工具
  14. 稀缺-我们是如何陷入贫穷与忙碌的 读后感
  15. 淘宝客优惠券领取微信小程序前台和后台源码
  16. 零基础【绘画板绘】SAI仿水墨笔刷教程(干货)
  17. pytorch distiller Weights Pruning Algorithms
  18. 【伍】学好财报是选出好公司的关键
  19. 数字 IC 技能拓展(1)Xilinx_Vivado_SDK_2019.1 安装详细教程
  20. html div 内部居中。

热门文章

  1. 不健康的细节-洗衣粉
  2. 培训机构到底好不好?学历重要吗?java
  3. C#/VB.NET 在PDF表格中添加条形码
  4. PAT-团体程序设计天梯赛-练习集-L1-039. 古风排版
  5. 网易云网络部署参考方案-网易云网络服务研发实践|网易云
  6. 数据结构课设之校园导航系统(迪杰斯特拉算法)
  7. 全志D1开发板 XR829蓝牙 Can‘t get device info: No such device 自我分析及解决方案
  8. 测试用例设计方法_错误推测法(游戏向)
  9. 【问题】以太坊私链连接钱包报错解决汇总
  10. The Wind River Registry on host localhost died unexpectedly