簡體   English   中英

scanf正在跳過掃描

[英]scanf is skipping scans

我正在用C編寫帶有多個scanfs的程序,但是運行它時,每當我進入讀取整數值的掃描時,它都會跳過它並放入一個不同的值,從而開始執行無窮循環。 我什至嘗試將每個scanfs分成多個函數,並且發生相同的事情。 我絕對不知道什么是錯的,或者該怎么做。

檢查返回值。 C庫函數出於某種原因返回狀態代碼。

人們用scanf遇到的主要問題是數據不是他們期望的。 這可能會導致部分掃描,使您處於文件中意外的位置以備將來掃描。 可能是導致無限循環的原因,通常可以通過確保返回值是您期望的值(嘗試掃描的項目數)來檢測到它。 如果不看代碼,很難說出來。

C99在7.19.6.4 The scanf function節中7.19.6.4 The scanf function

如果在任何轉換之前發生輸入失敗,則scanf函數將返回宏EOF的值。 否則,scanf函數將返回分配的輸入項數,如果早期匹配失敗,該數目可能少於所提供的輸入項數,甚至為零。

但是,幾乎總是應該將輸入檢索為 ,然后使用sscanf從那里進行處理,因為這是一種簡單的方法,可以嘗試對輸入數據進行多次掃描以查找不同格式的字符串,以進行多次掃描以找出哪種格式的字符串。線在。

例如,以下代碼是通過緩沖區溢出保護檢測以及緩沖區清除來檢索用戶輸入的安全方法,因此多余的輸入不會影響下一個輸入操作:

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

#define OK       0
#define NO_INPUT 1
#define TOO_LONG 2
static int getLine (char *prmpt, char *buff, size_t sz) {
    int ch, extra;

    // Get line with buffer overrun protection.
    if (prmpt != NULL) {
        printf ("%s", prmpt);
        fflush (stdout);
    }
    if (fgets (buff, sz, stdin) == NULL)
        return NO_INPUT;

    // If it was too long, there'll be no newline. In that case, we flush
    // to end of line so that excess doesn't affect the next call.
    if (buff[strlen(buff)-1] != '\n') {
        extra = 0;
        while (((ch = getchar()) != '\n') && (ch != EOF))
            extra = 1;
        return (extra == 1) ? TOO_LONG : OK;
    }

    // Otherwise remove newline and give string back to caller.
    buff[strlen(buff)-1] = '\0';
    return OK;
}

您可以通過以下方式調用此代碼:

char buff[50];
int rc = getLine ("What?> ", buff, sizeof(buff));
if (rc != OK) {
    // Error condition, either EOF or to long.
}
// Now use sscanf on buff to your heart's content,
//   remembering to check the return value.

如果您正在從stdin中讀取,則scanf將從按回車鍵結束的緩沖區中讀取。

第一個scanf將接受您要查找的內容,但其余緩沖區將保留。

對於代碼:

int num;
scanf("%d", &num);

並輸入:

1 2 3 4 5

num將為5,正如預期的那樣。

2 3 4 5

仍然會在緩沖區中,因此您運行的下一個scanf不會提示您輸入其他內容,而是將其作為輸入。

您的scanf可能正在從先前的緩沖區讀取殘留數據。

暫無
暫無

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

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