你的sscanf用對了嗎。本站提示廣大學習愛好者:(你的sscanf用對了嗎)文章只能為提供參考,不一定能成為您想要的結果。以下是你的sscanf用對了嗎正文
我們往常編寫的很多使用順序都會處置各種各樣的輸出,這些輸出或來自本地文件,或來自網絡,或來自用戶的輸出。明天,讓我們來看看sscanf這個和字符串相關的函數能夠給你帶來的費事。
上面是演示代碼,這段代碼將一些以字符串方式保管的數據加載到順序中。這些字符串可以來自任何中央,本演示代碼對字符串停止了硬編碼。
1 struct Data 2 { 3 char item1; 4 char item2; 5 char item3; 6 char item4; 7 }; 8 9 int main() 10 { 11 Data data; 12 memset(&data, 0, sizeof(data)); 13 14 char data1[] = "1"; 15 char data2[] = "2"; 16 char data3[] = "3"; 17 char data4[] = "4"; 18 19 sscanf_s(data4, "%d", &data.item4); 20 sscanf_s(data3, "%d", &data.item3); 21 sscanf_s(data2, "%d", &data.item2); 22 sscanf_s(data1, "%d", &data.item1); 23 24 printf_s("item1:%d\n", data.item1); 25 printf_s("item2:%d\n", data.item2); 26 printf_s("item3:%d\n", data.item3); 27 printf_s("item4:%d\n", data.item4); 28 29 getchar(); 30 return 0; 31 }
你覺得執行後果會是什麼?
奇異嗎?
剖析
讓我們剖析一下:
第19行代碼將4賦值給了item4,第20行代碼將3賦值給了item3, 第21行代碼將2賦值給了item2, 第22行代碼將1賦值給了item1。似乎沒什麼問題。
還是來調試下順序吧。
上面幾張圖片演示了順序在執行進程中的內存規劃
執行第一條sscanf_s前的內存規劃
執行第一條sscanf_s後的內存規劃
執行第二條sscanf_s後的內存規劃
執行第三條sscanf_s後的內存規劃
執行第四條sscanf_s後的內存規劃
到這裡,置信大家都曾經明白順序的輸入後果為何是1,0,0,0了。
演示代碼不只發作了內存越界,而且後續一切的輸出都掩蓋了上一條的執行後果。
罪魁禍首就是sscanf_s中的格式字符串"%d","%d"標明將輸出字符串作為一個int類型來保管到目的地址處。而演示代碼的書寫方式很顯然不契合Data這個構造體中各成員所聲明類型的要求。
將個數字符串修正為"%c"後,順序執行正確:
當然,我們其實可以在編譯階段發現這類問題
結語
經過明天這個演示,愈加讓自己明白了一定要多留意編譯時期的正告信息,盡全力將其消滅。
本博客僅僅演示了sscanf_s這類函數的冰山一角,關於其他需求留意的中央可以參考Format Specifiers Checking