我正在创建一个记录时间,用户ID和权重的应用。如何检查传递的第一个标记是否为整数?我以为我会使用isdigit,但这只适用于单个字符。如果第一个标记不是整数,我想输出无效时间。我目前正在使用
sscanf(userInput, "%d %s %f", ×tamp, userID, &weight);
如果第一个标记不是整数(例如有字母),我仍然得到一个我不想要的变量时间戳的数字。
int main()
{
char userInput[99];
int timestamp, timestampT = 0;
char userID[31];
userID[0] = 0;
float weight, weightT, day, rateW;
while(fgets(userInput, 99, stdin) != NULL){
sscanf(userInput, "%d %s %f", ×tamp, userID, &weight);
if(timestamp == 0 ){
printf("%s\n", "Invalid time");
}
else if(!isalpha(userID[0]) || userID[0]=='_' || userID[0] == 0){
printf("%s\n", "Illegal userID");
}
else if(weight < 30.0 || weight > 300.0){
printf("%s\n", "Illegal weight");
}
else if(timestampT > 0){
day = timestampT/86400;
rateW = (weightT -weight)/(day - timestamp/86400);
if(rateW > 10.0 || rateW < -10.0){
printf("%s\n", "Suspiciously large weight change");
}
}
else{
printf("%d %s %f \n", timestamp, userID, weight);
timestampT = timestamp;
timestamp = 0;
weightT = weight;
}
userID[0] = 0;
}
}
答案 0 :(得分:3)
简单方法:
char dummy;
sscanf( userInput, "%d%c %s %f", ×tamp, &dummy, userId, &weight );
if ( !isspace( dummy ))
// invalid timestamp input, handle as appropriate
%d
转换说明符告诉sscanf
在输入流中保留第一个非数字字符,该字符将由%c
转换说明符选取。如果此字符不是空格,则输入不是有效的整数字符串。
不太容易,但IMO的方式更为强大:
首先,以文字形式阅读您的时间戳:
char timestampStr[N+1]; // where N is the number of digits in the time stamp
...
sscanf(userInput, "%s %s %f", timestampStr, userID, &weight);
然后使用strtol
库函数将文本转换为整数值:
char *chk;
int tmp = (int) strtol( timestampStr, &chk, 10 );
转换后,chk
将指向timestampStr
中的第一个非数字字符;如果此字符不是空格或0终止符,则输入字符串不是有效整数:
if ( *chk == 0 || isspace( *chk ))
{
timestamp = tmp;
}
else
{
// invalid timestamp input, handle as appropriate
}
我更喜欢这种方法,因为如果输入无效,它不会向timestamp
分配任何内容;这对您的目的可能有关,也可能无关紧要。
修改强>
正如chux所指出的那样,你还应该检查sscanf
的返回值(我很少使用*scanf
函数进行交互式输入,所以我从来没有想过这个)。在第一种情况下,如果结果是&lt; 4,那么无论时间戳如何都会出现问题,应该抛弃整条线。类似地,在第二种情况下,如果结果是&lt; 3,你没有得到你想要的输入,你应该扔掉整条线。
在实践中,我所做的是使用fgets
阅读该行,然后使用strtok
将其分解为令牌,然后使用strtol
或strtod
执行任何操作必要时进行数字转换。