什么是 sscanf() 函數?
sscanf() 函數是 C 語言中的一個標準庫函數,它的作用是從一個字符串中按照指定的格式提取數據,并將其存儲到對應的變量中。它的原型如下:
int sscanf(const char *str, const char *format, ...);
其中,str
?是要解析的字符串,format
?是格式控制字符串,后面是一系列的指針參數,用來接收解析后的數據。sscanf() 函數返回成功匹配和賦值的個數,如果發生錯誤或到達字符串末尾,則返回 EOF。
sscanf() 函數的格式控制字符串
sscanf() 函數的格式控制字符串是由一些格式說明符組成的,每個格式說明符都以?%
?開始,用來指定要提取的數據的類型和方式。格式說明符的一般形式是:
%[*][width][modifiers]type
其中,各個部分的含義如下:
*
?是一個可選的星號,表示忽略該數據,不存儲到對應的參數中。width
?是一個可選的整數,表示要讀取的最大字符數。modifiers
?是一些可選的修飾符,用來指定數據的大小或精度,常見的有:h
?表示短整型(對于?d
,i
?和?n
),或無符號短整型(對于?o
,u
?和?x
)。l
?表示長整型(對于?d
,i
?和?n
),或無符號長整型(對于?o
,u
?和?x
),或雙精度浮點型(對于?e
,f
?和?g
)。L
?表示長雙精度浮點型(對于?e
,f
?和?g
)。
type
?是一個必需的字符,表示要提取的數據的類型,常見的有:c
?表示單個字符,如果指定了?width
,則會讀取?width
?個字符,并存儲到一個字符數組中。d
?表示十進制整數,數字前面的?+
?或?-
?號是可選的。e
,E
,f
,g
,G
?表示浮點數,包含了一個小數點,一個可選的前置符號?+
?或?-
,一個可選的后置字符?e
?或?E
,以及一個十進制指數。o
?表示八進制整數。s
?表示字符串,會讀取連續的非空白字符,直到遇到一個空白字符為止。u
?表示無符號的十進制整數。x
,X
?表示十六進制整數。[
?表示字符集合,會讀取符合指定字符集合的連續字符,直到遇到一個不符合的字符為止。字符集合可以用?-
?表示范圍,例如?[0-9]
?表示數字,也可以用?^
?表示取反,例如?[^a-z]
?表示非小寫字母。如果字符集合以?^
?開始,則?^
?不表示取反,而是表示本身,例如?[^^]
?表示非?^
?的字符。
sscanf() 函數的使用示例
下面給出一些使用 sscanf() 函數的示例,以及相應的輸出結果。
#include <stdio.h>int main()
{char str[100] = "2021-03-01 10:44:00"; // 要解析的字符串int year, month, day, hour, minute, second; // 存儲解析后的數據的變量int n; // 存儲 sscanf() 函數的返回值// 從字符串中按照指定的格式提取數據n = sscanf(str, "%d-%d-%d %d:%d:%d", &year, &month, &day, &hour, &minute, &second);// 輸出提取的數據和返回值printf("year = %d\n", year);printf("month = %d\n", month);printf("day = %d\n", day);printf("hour = %d\n", hour);printf("minute = %d\n", minute);printf("second = %d\n", second);printf("n = %d\n", n);return 0;
}
輸出結果為:
year = 2021
month = 3
day = 1
hour = 10
minute = 44
second = 0
n = 6
從輸出結果可以看出,sscanf() 函數成功地從字符串中提取了年月日時分秒的數據,并存儲到對應的變量中,返回值為 6,表示有 6 個數據被匹配和賦值。
下面再看一個使用字符集合的示例:
#include <stdio.h>int main()
{char str[100] = "Hello, world!"; // 要解析的字符串char word1[20], word2[20]; // 存儲解析后的數據的變量int n; // 存儲 sscanf() 函數的返回值// 從字符串中按照指定的格式提取數據n = sscanf(str, "%[^,], %s", word1, word2);// 輸出提取的數據和返回值printf("word1 = %s\n", word1);printf("word2 = %s\n", word2);printf("n = %d\n", n);return 0;
}
輸出結果為:
word1 = Hello
word2 = world!
n = 2
從輸出結果可以看出,sscanf() 函數使用了字符集合?[^,]
?來提取第一個逗號之前的字符串,然后使用了?s
?來提取第一個空格之后的字符串,返回值為 2,表示有 2 個數據被匹配和賦值。
sscanf() 函數的注意事項
在使用 sscanf() 函數時,需要注意以下幾點:
- sscanf() 函數會從字符串的開頭開始解析,如果遇到不符合格式的字符,就會停止解析,并返回已經匹配和賦值的個數。因此,要保證字符串的格式和格式控制字符串的格式一致,否則可能會導致解析失敗或不完全。
- sscanf() 函數的格式控制字符串中可以包含空格字符、制表符、換行符等,它們會被忽略,不影響解析。但是,如果要匹配字符串中的空白字符,就不能使用?
s
?類型,而要使用?c
?類型或字符集合類型,并指定?width
?為 1。 - sscanf() 函數的后面的指針參數必須和格式說明符的類型一致,否則可能會導致數據錯誤或內存溢出。例如,如果要提取一個整數,就不能使用?
char *
?類型的參數,而要使用?int *
?類型的參數,并在變量名前加上?&
?符號,表示取地址。 - sscanf() 函數不會在提取的字符串后面自動添加空字符,因此,如果要將提取的字符串作為一個完整的字符串使用,就需要手動在后面添加空字符,或者在定義字符數組時多預留一個空間,用來存儲空字符。