簡體   English   中英

C sscanf 驗證輸入格式

[英]C sscanf to validate input format

我想編寫一個程序,它從用戶那里讀取一行輸入,格式如下: <Name>,<Age>,<City>

  • 名稱只能包含英文字母、空格和-
  • 年齡必須是介於 18 到 120 之間的 integer。
  • City 必須包含英文字母和- only。

它們中的每一個都可以是 49 號。我想存儲信息並打印一個信息性錯誤將打印錯誤輸入。

我的代碼如下:

    char str[150];
    char input[3][50] = { 0 };
    int num = 0;
    if (fgets(str, 150, stdin) != NULL) {
        num = sscanf(str, "%[a-zA-Z -],%[0-9],%[a-zA-Z-]", input[0], input[1], input[2]);
    }
    if (num < 3) {
        printf("ERROR\n");
    }

問題是對於諸如Name1$#,20,NYBest,19,Rome123Best,100,Paris1$之類的輸入不會打印錯誤,其中城市格式錯誤(帶有尾隨字符)。 有什么方法可以使用sscanf解決它?

您可以根據需要使用sscanf()和字符類,但格式字符串存在一些小問題:

  • AZ采用 ASCII 編碼或至少是字母連續的編碼。
  • 尾隨-具有特殊含義,將破折號放在第一個 position 以明確匹配破折號。
  • 沒有長度前綴,因此超過 49 個字符的名稱或城市將溢出目標數組。

而不是使用fgets() ,您應該手動閱讀該行以檢測過長的行。

您可以添加額外的%c以檢查行尾的額外字符。 如果您不打算使用字段值,則不需要存儲轉換后的值,但您必須轉換數字以檢查其值是否在請求的范圍內:

    char str[150];
    char name[50];
    char city[50];
    char agestr[4];
    size_t i;
    int c, age, pos, n;

    for (i = 0; (c = getchar()) != EOF && c != '\n'; i++) {
        if (i < sizeof(str) - 1)
            str[i] = (char)c;
    }
    if (c == EOF && i == 0) {
        printf("end of file\n");
        return -1;
    }
    if (i >= sizeof(str)) {
        printf("line too long\n");
        return 0;
    }
    str[i] = '\0';
    pos = 0;
    /* validate the name */
    if (sscanf(str + pos, "%49[-a-zA-Z ]%n", name, &n) != 1 || str[pos + n] != ',') {
        printf("invalid name\n");
        return 0;
    }
    pos += n + 1;
    /* validate the age */
    if (str[pos] == '0' || sscanf(str + pos, "%3[0-9]%n", agestr, &n) != 1 || str[pos + n] != ',') {
        printf("invalid age\n");
        return 0;
    }
    age = atoi(agestr);
    if (age < 18 || age > 120) {
        printf("age out of range: %d\n", age);
        return 0;
    }
    pos += n + 1;
    /* validate the city */
    if (sscanf(str + pos, "%49[-a-zA-Z]%n", city, &n) != 1 || str[pos + n] != '\0') {
        printf("invalid city\n");
        return 0;
    }
    /* Input was validated... proceed */

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM