簡體   English   中英

使用sscanf從fgets讀取

[英]Using sscanf for reading from fgets

我仍然對編程有點陌生,並且在編譯程序時收到以下警告:

warning: too many arguments for format [-Wformat-extra-args]
int c = sscanf(Input, "%f %f %*[^\n]%*d", &start, &end, &rows);
                      ^~~~~~~~~~~~~~~~~~

這是我的代碼:

fgets(Input, 256, stdin);
int count = 0;
char *token = strtok(Input, " \n\t");
count++;

while(token != NULL)
{
    token = strtok(NULL, " \n\t");
    count++;
}

if(count == 3)
{
    int c = sscanf(Input, "%f %f %*[^\n]%*d", &start, &end, &rows);
    if(c != 3)
    {
        printf("\nError: Illegal input!\n");
    }
}

如果有三個單獨的字符串,我想讀的是三個數字。 我知道sscanf可用於驗證輸入(因為它返回成功掃描的次數)。

例如,這些數字是1 6 8
並且應該為“ 0 ab 19 ”之類的輸入打印“非法輸入”。

我也嘗試過將令牌存儲到字符串數組中,但是在驗證方面存在問題。

所以我想問的是,這是正確的方法嗎?

提前致謝。

您的代碼失敗的原因有兩個:

  • 您使用strtok()執行的解析會修改Input數組,因此隨后的sscanf()轉換將失敗,因為只會看到第一個字段。
  • 格式字符串"%f %f %*[^\\n]%*d"包含2個用於float值的轉換規范和2個具有禁止存儲的轉換。 傳遞3個目標參數是不正確的。

這是您可以在一次調用中執行轉換和驗證的方法:

int read_values(void) {
    char input[256];
    char str[256];
    float start, end;
    int rows;
    char c;

    if (fgets(input, sizeof(input), stdin)) {
        *string = '\0';
        if (sscanf(input, "%f%f%d %c", &start, &end, &rows, &c) == 3) {
            // start, end and rows were read and converted properly
            // you might way to perform further validation steps on their values.
        } else
        if (sscanf(input, "%s%f%f%d %c", str, &start, &end, &rows, &c) == 4) {
            // there was an initial word before the 3 numbers
        } else {
            printf("Error: invalid input: %s", input);
            return -1;
        }
        return 0;
    } else {
        printf("Error: premature end of file\n");
        return -1;
    }
}

且僅當sscanf()可以轉換2個浮點數和一個整數並且除尾隨空白外該行上沒有其他字符,才返回3。 前導空格和數字之間的空格也將被忽略。

如果可選字符串可以包含多個單詞,則可以使用迭代方法:可以嘗試跳過單詞,直到解析成功或輸入被完全消耗為止:

#include <stdio.h>
#include <string.h>

int read_values(void) {
    char input[256];
    float start, end;
    int i, rows;
    char c;

    if (fgets(input, sizeof(input), stdin)) {
        for (i = 0;;) {
            if (input[i] == '\0') {
                printf("Error: invalid input: %s", input);
                return -1;
            }
            if (sscanf(input + i, "%f%f%d %c", &start, &end, &rows, &c) == 3) {
                break;
            }
            i += strspn(input + i, " \t\n");   // skip white space
            i += strcspn(input + i, " \t\n");  // skip a word
        }
        // The initial string has `i` characters
        // start, end and rows were read and converted properly
        // you might want to perform further validation steps on their values.
        printf("string: %.*s\n", i, input);
        printf("start: %f\n", start);
        printf("end: %f\n", end);
        printf("rows: %d\n", rows);
        return 0;
    } else {
        printf("Error: premature end of file\n");
        return -1;
    }
}

暫無
暫無

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

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