你的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