ICode9

精准搜索请尝试: 精确搜索
首页 > 其他分享> 文章详细

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

2022-04-03 13:04:24  阅读:180  来源: 互联网

标签:字符 scanf C语言 空格 001 字符串 格式 整形 输入


 

 概要

在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-不同输入下结果对比

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

 

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区别

标签:字符,scanf,C语言,空格,001,字符串,格式,整形,输入
来源: https://www.cnblogs.com/blogyxl/p/yxl_bky_c001.html

本站声明: 1. iCode9 技术分享网(下文简称本站)提供的所有内容,仅供技术学习、探讨和分享;
2. 关于本站的所有留言、评论、转载及引用,纯属内容发起人的个人观点,与本站观点和立场无关;
3. 关于本站的所有言论和文字,纯属内容发起人的个人观点,与本站观点和立场无关;
4. 本站文章均是网友提供,不完全保证技术分享内容的完整性、准确性、时效性、风险性和版权归属;如您发现该文章侵犯了您的权益,可联系我们第一时间进行删除;
5. 本站为非盈利性的个人网站,所有内容不会用来进行牟利,也不会利用任何形式的广告来间接获益,纯粹是为了广大技术爱好者提供技术内容和技术思想的分享性交流网站。

专注分享技术,共同学习,共同进步。侵权联系[81616952@qq.com]

Copyright (C)ICode9.com, All Rights Reserved.

ICode9版权所有