确保scanf只读取dd.mm.yyyy

时间:2018-06-12 08:11:39

标签: c

我正在寻找解决问题的方法。 我想扫描日期(dd.mm.yyyy)。我需要确保输入采用这种格式,只有0<一天< 31; 0<月份< 13; 2018年<一年。

对于任务的长度,我这样做:

printf("Please typ in the Task: \t");
scanf("%s", &what);
while (strlen(what) >= MAX) {
    clearScanf();
    printf("The task must contain a maximum of %d :\t", MAX - 1);
    scanf("%s", &what);
}

但我不知道如何确保,我的

printf("Pls put in the Deadline (dd.mm.yyyy): \t");
scanf("%s", when);

不会使用角色,但仍然使用'。'之间。

在scanf之后,我想通过以下方式将所有内容提供给我的结构:

strcpy(temp->name, what);
strcpy(temp->deadline, when);
temp->next = pointer;

但我不知道,如何给予一年,一年和一天的回报。

2 个答案:

答案 0 :(得分:3)

使用scanf + sscanf

int day, month, year;
for(;;)                                        /* Infinite loop */
{
    scanf("%s", when);
    char temp;
    if(sscanf(when, "%2d.%2d.%4d%c", &day, &month, &year, &temp) != 4 ||
       temp != '\n')                           /* Check if no extra characters were typed after the date */
    {
        fputs("Invalid format!\n", stderr);
        clearScanf();                          /* Assuming this function of yours clears the stdin */
    }
    else if(!(0 < date && date <= 31) ||       /* Valid range checks */
            !(0 < month && month <= 12) ||
            !(0 < year && year <= 2018))
    {
        fputs("Invalid date!\n", stderr);
    }
    else
    {
        break;
    }
}

这样做,它告诉scanf首先扫描一个字符串,然后使用sscanf从中提取数据。

sscanf首先提取2个数字,然后是一个点,再两个数字,一个点,然后是4个数字,最后是一个字符并分配给相应的参数。该字符用于检查用户是否输入了更多字符。

sscanf返回成功扫描和分配的项目数。在这种情况下,如果它返回4,它就成功提取了所有内容。

答案 1 :(得分:0)

编写自己的格式检查功能:

bool is_correctly_formatted(const char* s) {

    if(!isdigit(s[0])) return false;
    if(!isdigit(s[1])) return false;
    if('.' != s[2]) return false;
    if(!isdigit(s[3])) return false;
    if(!isdigit(s[4])) return false;
    if('.' != s[5]) return false;
    if(!isdigit(s[6])) return false;
    if(!isdigit(s[7])) return false;
    if(0 != s[8]) return false;

    return true;

}

然后您可以像:

一样使用它
#define MAX 8

int main(int argc, char** argv) {

    /* Space for MAX chars + line feed + terminal zero */
    char what[MAX + 1 + 1] = {0};

    /* Ensure that scanf reads in at most as many chars as can be safely written to `what` */
    char format[MAX + 2 + 1] = {0};
    snprintf(format, sizeof(format), "%%%ds", MAX + 1);

    do {
        printf("%s Please type in the Task: ", format);
        scanf(format, &what[0]);
        /* chomp the trailing '\n' */
        if(isspace(what[MAX + 1])) what[MAX + 1] = 0;
        printf("Entered %s\n", what);
    } while (! is_correctly_formatted(what));
}

这使您可以尽可能灵活地进行预期。您甚至可以使用某种regex library

注意:读取字符串将包含尾随换行符,因此您必须将其删除...