0
我是比較新的C和想知道如何防止溢出從輸入...C:如何防止使用scanf溢出輸入?
因此,例如,我有:
scanf("%d", &a);
其中A是整數。
那麼,我能做些什麼來防止有人輸入比最大整數大的數字?由於我正在處理的問題的限制,您必須使用scanf
。我如何去限制輸入?
在此先感謝。
我是比較新的C和想知道如何防止溢出從輸入...C:如何防止使用scanf溢出輸入?
因此,例如,我有:
scanf("%d", &a);
其中A是整數。
那麼,我能做些什麼來防止有人輸入比最大整數大的數字?由於我正在處理的問題的限制,您必須使用scanf
。我如何去限制輸入?
在此先感謝。
'對阻止用戶輸入非常具有挑戰性。
沒有魔力伸手去阻止用戶在鍵盤上跳動。
但代碼可以限制它讀取的內容。
1)scanf()
很難限制。它可能不會在溢出時設置errno
。代碼可以將char
的數目限制爲9.這是第一步,但不能輸入「1000000000」或「00000000000000001」等值。
// Assume INT_MAX = 2,147,483,647.
scanf("%9d", &a);
2)迂腐方法將使用fgetc()
。接下來的方法是unsigned
。 int
需要多一點。
unsigned a = 0;
int ch = fgetc(stdin);
while (isspace(ch)) {
ch = fgetc(stdin);
}
while (isdigit(ch)) {
unsigned newa = a*10 + ch - '0';
if (newa < a) {
break; // overflow detected.
}
a = newa;
ch = fgetc(stdin);
}
ungetc(ch, stdin); // Put back `ch` as it was not used.
3)但我更喜歡改變目標,並且只是再次告訴用戶,即使它意味着閱讀更多字符。
// 0:success or EOF
int Read_int(const char *prompt, int *dest, int min, int max) {
for (;;) {
char buf[sizeof(int)*3 + 3];
fputs(prompt, stdout);
if (fgets(buf, sizeof buf, stdin) == NULL) {
return EOF;
}
char *endptr;
errno = 0;
long l = strtol(buf, &endptr, 10);
if (buf == endptr || *endptr != '\n') {
continue; // only \n entered or invalid `chars` entered
}
if (!errno && l >= min && l <= max) {
*dest = (int) l;
return 0; // success
}
}
}
int a;
Read_int("Enter an `int`\n", &a, INT_MIN, INT_MAX);
使用'scanf'來讀取一個字符串,然後自己解析它? –
理論上,您可以看到errno是否爲超出範圍錯誤的ERANGE。然而,這並不是針對scanf規定的標準。見http://linux.die.net/man/3/scanf'''C89和C99和POSIX.1-2001標準沒有指定ERANGE錯誤''換句話說,如果你使用'strtol'需要讀取整數,同時還能夠檢查溢出。 – Brandin
如果你必須使用scanf,一個簡單的方法是使用scanf(它有一個更大的範圍)來讀取'double',做你自己的範圍檢查,然後將結果轉換爲一個'int',如果它符合你的標準。只要您的有效整數範圍不是太大,這將工作而不丟失信息。 – Brandin