2012-02-12 45 views
3

我在網上發現,在C++中有一個替代方案,但簡單的老C呢?我很欣賞任何提示或建議。在C中,sscanf的安全選擇是什麼?

+2

與C中的一些標準函數不同,'sscanf'可以安全地使用。因爲在C中做任何事情都需要謹慎,所以您可能需要更具體地瞭解您的特定用例,以針對您正在考慮的任何問題獲得「更安全」的解決方案。 – 2012-02-12 01:43:21

+0

嗯,sscanf比...更安全嗎? – Coffee 2012-02-12 01:45:32

+0

在哪些方面安全?你有關於你的特定用例嗎? – Johnsyweb 2012-02-12 01:53:33

回答

7

這取決於你想要用它做什麼。

由於您在內存中有字符串,因此您可以通過小心所傳遞的參數來安全地避免緩衝區溢出。例如,如果你正在掃描一個字符串,使用"%s",只需使用足夠大的目標緩衝區來保存可能存在的最大字符串(並確保源緩衝區是有效的字符串,即它是'\0'封端的)。

所有*scanf()函數的一個危險是,如果您正在掃描一個數值並且輸入值太大而無法在目標類型中表示,則行爲是未定義的。例如,這個程序:

#include <stdio.h> 
int main(void) { 
    const char *s = "999999999999999999999999999"; 
    int n; 
    sscanf(s, "%d", &n); 
    printf("n = %d\n", n); 
    return 0; 
} 

是未定義行爲(除非INT_MAX真的非常大)。

您可以使用strto*()功能安全掃描數值:strtol()strtoll()strtoul()strtoull()strtof()strtod()strtold()。他們對錯誤的行爲有點棘手,但至少它是明確的。

4

我相信你正在尋找「m」修飾符。它動態分配內存來保存提取的字符串,以避免緩衝區溢出。唯一的缺點是它是一個GNU擴展,例如MSVC可能不會識別它。

這是關於該主題的existing Stack Overflow answer

這裏有一個如何使用它的一個例子:

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

int main(void) 
{ 
    char *str; 
    printf("Enter your name:\n"); 
    scanf("%ms", &str); 

    printf("Hello %s!\n", str); 
    free(str); 
    return 0; 
} 
+0

OP正在詢問關於plain-old-C的問題,所以可能不是這樣的擴展。 POSIX中還有'%as' – 2017-04-25 04:46:00