我让用户输入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上编译并运行吗?
答案 0 :(得分:1)
您的问题可能是特定于操作系统的。我假设它可能是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兼容的操作系统。
拥有sscanf
转化规范时,请注意%n
的结果。该手册页告诉标准可能在那个角落案例中是矛盾的。
如果您的操作系统不符合Posix(例如Windows),那么您应该找到另一种方法。如果您接受将线路尺寸限制为例如128你可以编码
char line[128];
memset (line, 0, sizeof(line));
fgets(line, sizeof(line), stdin);
ssize_t linelen = strlen(line);
然后你会附加前一个(即第一个)代码块的sscanf
和后续代码(但没有最后一行调用free(line)
)。
答案 1 :(得分:1)
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
。
如果在%1u
中查找1位十进制数字,请使用unsigned
如果在%1d
中查找1个十进制数字,请使用int
。
array[0]=line[0]-'0'; ...
,不错,但有一些缺点。它不执行良好的错误检查(非数字)也不像第一个那样处理十六进制数字。此外,它不允许引导或散布空间。
答案 2 :(得分:0)
您要获得的是4位数字,它们之间有或没有空格。为此,您可以将字符串作为输入,然后逐个字符检查该字符串并计算字符串中的数字位数(以及空格和其他字符),并执行所需的操作/显示所需的消息。
答案 3 :(得分:0)
你不能用scanf做到这一点。问题是,有一些方法可以让scanf搜索4个数字之后的某些内容,但是如果用户没有输入更多数字,它们将只是坐在那里等待更多的用户输入。所以你需要使用gets()或fgets()并解析字符串来做到这一点。
答案 4 :(得分:0)
你可能更容易改变你的程序,所以你一次要求一个数字 - 然后你问了4次,你已经完成了它,所以这些内容,伪代码:
i = 0
while i < 4
ask for number
scanf number and save in array at index i
答案 5 :(得分:0)
E.g
#include <stdio.h>
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<size;++i){
printf("%x", array[i]);
}
printf("\n");
return 0;
}