- C和C++安全編碼(原書第2版)
- (美)Robert C.Seacord
- 654字
- 2020-10-30 17:56:44
2.5.4 動態(tài)分配函數(shù)
ISO/IEC TR 24731-2描述了來自POSIX的getline()函數(shù)。getline()函數(shù)的行為與fgets()類似,但提供了一些額外的功能。首先,如果輸入行過長,那么該函數(shù)使用realloc()調(diào)整緩沖區(qū)的大小,而不是截斷輸入。其次,如果它執(zhí)行成功,則返回讀取的字符數(shù),這對于確定在輸入的換行符之前是否有任何空字符是非常有用的。getline()函數(shù)僅適用于使用malloc()分配的緩沖區(qū)。如果傳入一個空指針,則函數(shù)getline()會分配一個大小足夠容納輸入的緩沖區(qū)。因此,隨后用戶必須明確地用free()釋放該緩沖區(qū)。當(dāng)分隔符等于換行符時,getline()函數(shù)相當(dāng)于getdelim()函數(shù)(getdelim()函數(shù)也在ISO/IEC TR 24731-2中定義)。例2.12中所示的程序片段使用getline()函數(shù)從stdin中讀取一行文本。
例2.12 使用函數(shù)getline()從stdin中讀入
01 int ch; 02 char *p; 03 size_t buffer_size = 10; 04 char *buffer = malloc(buffer_size); 05 ssize_t size; 06 07 if ((size = getline(&buffer, &buffer_size, stdin)) == -1) { 08 /* 處理錯誤 */ 09 } else { 10 p = strchr(buffer, '\n'); 11 if (p) { 12 *p = '\0'; 13 } else { 14 /* 未找到換行符, 刷新標(biāo)準(zhǔn)輸入至行尾 */ 15 while (((ch = getchar()) != '\n') 16 && !feof(stdin) 17 && !ferror(stdin) 18 ); 19 } 20 } 21 22 /* ... 對緩沖區(qū)進(jìn)行處理 ... */ 23 24 free(buffer);
getline()函數(shù)返回寫入緩沖區(qū)的字符數(shù)目,包括換行符,如果在文件結(jié)束前遇到它。如果發(fā)生讀取錯誤,流中的錯誤標(biāo)記就被設(shè)置,函數(shù)getline()返回–1。因此,此函數(shù)的設(shè)計(jì)違反《C安全編碼標(biāo)準(zhǔn)》[Seacord 2008],“ERR 02-C.避免帶內(nèi)錯誤標(biāo)志”,因?yàn)閟size_t類型是以提供帶內(nèi)錯誤標(biāo)志為目的而被創(chuàng)建的。
注意,此代碼也沒有檢查malloc()是否執(zhí)行成功。然而,如果malloc()失敗,它返回NULL,這被傳遞給getline()函數(shù),getline()函數(shù)將及時地分配它自己的一個緩沖區(qū)。
表2.4總結(jié)了本節(jié)中描述的gets()的一些替代函數(shù)。所有這些函數(shù)都可以安全地使用。
表2.4 gets()的替代函數(shù)
- C++面向?qū)ο蟪绦蛟O(shè)計(jì)(第三版)
- SQL學(xué)習(xí)指南(第3版)
- Mastering SVG
- Python 深度學(xué)習(xí)
- PHP程序設(shè)計(jì)(慕課版)
- Instant Zepto.js
- iOS應(yīng)用逆向工程(第2版)
- PHP+MySQL網(wǎng)站開發(fā)項(xiàng)目式教程
- Python Data Analysis Cookbook
- 學(xué)習(xí)OpenCV 4:基于Python的算法實(shí)戰(zhàn)
- 移動增值應(yīng)用開發(fā)技術(shù)導(dǎo)論
- Mastering AWS Security
- Julia數(shù)據(jù)科學(xué)應(yīng)用
- Python預(yù)測分析與機(jī)器學(xué)習(xí)
- Java程序設(shè)計(jì)實(shí)用教程(第2版)