验证scanf的输入

时间:2014-11-01 20:41:10

标签: c

我需要以这种确切的格式阅读小时:分钟。我用:

    int hours, minutes;

    if (scanf("%d:%d", &hours, &minutes)!= 2)
    {
        printf("Wrong input.\n");
        return 1;
    }
else if (minutes>60 || minutes<0 || hours<0)
    {
        printf("Wrong input.\n");
        return 1;
    }

    time = hours*60 + minutes;

    /*read another time interval */
     if (scanf("%d:%d", &hours, &minutes)!= 2)
    {
        printf("Wrong input 2.\n");
        return 1;
    }
else if (minutes>60 || minutes<0 || hours<0)
    {
        printf("Wrong input 2.\n");
        return 1;
    }
   ...

工作正常,但我需要得到错误的输入&#34;也有人进入的情况,例如5:38abc

2 个答案:

答案 0 :(得分:1)

将运算符添加到格式字符串以匹配换行符:

int hours, minutes;
char str[2];

if (scanf("%d:%d%1[\n]", &hours, &minutes, str)!= 3)

%[\n]匹配换行符,字段宽度1使其在正好1个字符后停止匹配。

答案 1 :(得分:0)

传统方法是使用getline(3)fgets(3)读取整行(因此行在缓冲区中),然后解析该行。您可以使用sscanf(3) - 也许使用其%n说明符 - 或者您可以使用例如{...}手动解析该行。 strtol(3)(设置结束指针)。

类似于:

int endpos= -1;
char linbuf[32];
memset(linbuf, 0, sizeof(linbuf));
if (!fgets(linbuf, sizeof(linbuf)) exit(EXIT_FAILURE);
if (sscanf(linbuf, "%O2d:%02d%n", &hour, &minute, &endpos)<2)
   exit(EXIT_FAILURE);
if (endpos!=6) exit(EXIT_FAILURE);
if (hour<0 || minute<0 || hour>=24 || minute>=60) exit(EXIT_FAILURE); 

当然,您会以更加用户友好的拒绝方式替换exit(EXIT_FAILURE);

顺便说一句,您应指定1:2是否为可接受的输入,或者您是否需要01:02。你会接受一个空行代表中午吗?