從printf談開去………

來源:互聯網
上載者:User
這周六為系統捉蟲,無意中搜尋了整個工程,赫然發現無數個sprintf、wsprintf以及strcpy這類的函數遍布各個檔案,吃驚之餘細細查看,差點暈倒,雖然早就在公用標頭檔裡把這些函數#undef掉了(#include <strsafe.h>),但有的同事因為種種原因沒有include這個公用標頭檔(雖然這個公用標頭檔是先行編譯標頭檔),所以就忽略了這些函數的危險性...一、危險指數五星的strcpy()strcpy是眾所周知的最危險函數之一,它不判斷目標緩衝區是否足夠長,而strncpy要好一點,但它從某種意義上講,卻比strcpy還危險方:當目標緩衝區滿時,它不在尾部加零,也就是說,程式員也許會以為用了個安全的函數,結果拷貝過去的字串卻可能不是以零結尾!!

這個函數的替代品是strsafe.h中的StringCchCopy()二、危險且低效的sprintf()sprintf(以及printf系列)不但危險,而且低效。首先,它與strcpy一樣,沒有判斷目標緩衝區的長度,其次,它只能在運行時刻判斷參數的類型和個數(也就是說,如果你的格式字元指定了“%s: %d”,但你傳的參數個數不符,或者類型不符,只有在運行時刻才會爆發出來)。從安全形度上講,這個函數的替代品是strsafe.h中的StringCchPrintf(),但如果同時再考慮效率,用C++的輸出資料流更好(比如ostringstream),因為輸出資料流的格式化是在編譯時間刻決定的。三、printf系列的錯誤用法(同樣適用於StringCchPrintf) StringCchPrintf(outString, countOfOutBuffer, sourString)這種用法是相當危險的,它希望達到與StringCchCopy相同的效果,但它會在sourString中包含有“%d %s”這種程式員意料之外的冬冬時,產生嚴重的後果。正確的做法是:無論在任何情況下,printf系列函數都必須包含“明確的格式化字串”,比如sprintf(outString, "%s", sourString)。 四、貌似安全的strsafe.h中的系列函數StringCchCopy等函數,有一個很討厭的地方,就是它們不判斷源字元指標是否為NULL,也就是說,如果我們傳遞一個NULL指標給它,希望它理解為一個空串,而它卻會產生一個零地址訪問違例。這個也許並不嚴重,但卻會讓漫不經心不仔細閱讀文檔的程式員大吃一驚,而我這裡想說的是,這個並不是它們真正不安全的地方,真正不安全的地方其實在於它們並未把程式員從“必然管理字串長度和零結尾”中解脫出來,比方說程式員會提供一個錯誤的目標緩衝區長度,特別是在寬字元環境下,錯誤地傳遞了目標緩衝區的位元組數,而不是字元數。五、幸好有了STLSTL提供的模板類basic_string規避和解決了上述所有問題,讓C++程式員也擁有了類似於DELPHI中的原生String,再配合輸入輸出資料流(輸入資料流解決格式化輸入問題、輸出資料流解決了格式化輸出),從此“必須管理字串及緩衝區長度”、“必須補零”等問題,不再是C++程式員需要考慮的了!六、你還只是一個C程式員嗎?拋開OO不談,如果你還在自己管理字串,那你就還只是一個C程式員。(附註:不代表BS這門語言以及它的程式員們,只是在字串這個軟脅上,我們應該能做得更好)。

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.