检查用户输入数组是否太长?

我让用户输入4个数字。 它们可以输入:1 2 3 4或1234或1 2 34等我正在使用

int array[4]; scanf("%1x%1x%1x%1x", &array[0], &array[1], &array[2], &array[3]); 

但是,如果用户输入太多数字,我想显示错误:12345或1 2 3 4 5或1 2 345等。

我怎样才能做到这一点?

我是C的新手,所以请尽量解释。

//

谢谢你的帮助。 我现在要做的是:

 char line[101]; printf("Please input); fgets(line, 101, stdin); if (strlen(line)>5) { printf("Input is too large"); } else { array[0]=line[0]-'0'; array[1]=line[1]-'0'; array[2]=line[2]-'0'; array[3]=line[3]-'0'; printf("%d%d%d%d", array[0], array[1], array[2], array[3]); } 

这是一种明智和可接受的方式吗? 它编译并似乎适用于Visual Studios。 它会在C上编译和运行吗?

OP处于正确的轨道上,但需要进行调整以处理错误。

使用scanf()的当前方法可用于检测问题,但不能很好地恢复。 相反,使用fgets()/sscanf()组合。

 char line[101]; if (fgets(line, sizeof line, stdin) == NULL) HandleEOForIOError(); unsigned arr[4]; int ch; int cnt = sscanf(line, "%1x%1x%1x%1x %c", &arr[0], &arr[1], &arr[2],&arr[3],&ch); if (cnt == 4) JustRight(); if (cnt < 4) Handle_TooFew(); if (cnt > 4) Handle_TooMany(); // cnt == 5 

ch捕获4个数字后的任何潜伏的非空白char
如果在unsigned查找1个十进制数字,请使用%1u
如果在int查找1个十进制数字,请使用%1d


OP 2nd approach array[0]=line[0]-'0'; ... array[0]=line[0]-'0'; ... ,不错,但有一些缺点。 它不执行良好的错误检查(非数字)也不像第一个那样处理hex数字。 此外,它不允许引导或散布空间。

您的问题可能是特定于操作系统的。 我假设它可能是Linux。

您可以首先使用getline(3) (或readline(3) ,甚至fgets(3)读取整行,如果您接受为输入行大小设置上限)然后解析该行(例如使用sscanf(3)并使用%n格式说明符)。 不要忘记测试sscanf的结果(读取项目的数量)。

所以也许是这样的

 int a=0,b=0,c=0,d=0; char* line=NULL; size_t linesize=0; int lastpos= -1; ssize_t linelen=getline(&line,&linesize,stdin); if (linelen<0) { perror("getline"); exit(EXIT_FAILURE); }; int nbscanned=sscanf(line," %1d%1d%1d%1d %n", &a,&b,&c,&d,&lastpos); if (nbscanned>=4 && lastpos==linelen) { // be happy do_something_with(a,b,c,d); } else { // be unhappy fprintf(stderr, "wrong input line %s\n", line); exit(EXIT_FAILURE); } free(line); line=NULL; 

一旦你拥有整行,你可以通过其他方式解析它,比如连续调用strtol(3) 。

然后,问题是如果stdin有多行,会发生什么。 在这种情况下,我猜不出你想要什么。 也许feof(3)是相关的。

我相信我的解决方案可能不是特定于Linux的,但我不知道。 它可能适用于符合Posix 2008标准的操作系统。

具有%n转换规范时,请注意sscanf的结果。 该手册页告诉标准可能在该角落情况下是矛盾的。

如果您的操作系统不符合Posix(例如Windows),那么您应该找到另一种方法。 如果您接受将行大小限制为例如128,则可以编码

 char line[128]; memset (line, 0, sizeof(line)); fgets(line, sizeof(line), stdin); ssize_t linelen = strlen(line); 

然后你附加sscanf并跟随前一个(即第一个)代码块的代码(但没有最后一行调用free(line) )。

你想要得到的是4位数字,它们之间有或没有空格。 为此,您可以将字符串作为输入,然后逐字符检查该字符串并计算字符串中的数字位数(以及空格和其他字符),并执行所需的操作/显示所需的消息。

你不能用scanf做到这一点。 问题是,有一些方法可以让scanf搜索4个数字之后的某些内容,但是如果用户没有输入更多数字,它们将只是坐在那里等待更多的用户输入。 所以你需要使用gets()或fgets()并解析字符串来做到这一点。

你可能更容易改变你的程序,所以你一次要求一个数字 – 然后你问了4次,你已经完成了它,所以在这些方面,伪代码:

 i = 0 while i < 4 ask for number scanf number and save in array at index i 

例如

 #include  int main(void){ int array[4], ch; size_t i, size = sizeof(array)/sizeof(*array);//4 i = 0; while(i < size){ if(1!=scanf("%1x", &array[i])){ //printf("invalid input"); scanf("%*[^0123456789abcdefABCDEF]");//or "%*[^0-9A-Fa-f]" } else { ++i; } } if('\n' != (ch = getchar())){ printf("Extra input !\n"); scanf("%*[^\n]");//remove extra input } for(i=0;i