沒有自己做過輸入輸出函數的人,在使用scanf("%d", &x)這樣的函數輸入數據時,覺得在鍵盤上敲下123是一個整數,其實是個誤區。事實上,那是在輸入一個字符串"123",這個字符串進入scanf()之後,scanf()函數根據格式碼"%d"判斷,應該把輸入解釋成十進制整數,於是開始對這個字符串做變換處理(就像平時做練習那樣,把字符串變成數字或把數字變成字符串,很多人都做過的),然後把變換得到的結果,賦值給x(必須使用x的地址指針,原因是scanf()無法返回多個數據,所以才要用指針賦值,其實你完全可以自編一個不用指針的輸入函數,直接返回數據)。由於是指針賦值,所以scanf()並不理會目的變量x是否真的能夠容納結果數值,即使x其實是一個char,scanf()也是根據"%d"指示當x是int強行灌入數據,這樣,各種各樣的運行時錯誤就千奇百怪地冒出來了,全部都是這樣造成的。
同樣,在printf("%d", 123)的時候,我們看到的輸出其實是字符串(char[4]),不是你以為的整數。因此,只要你用fprinft(fp, "%d", x)輸出,那麼就必須用fscanf(fp, "%d", &x)讀回來,字符串對字符串,做逆運算;如果用fwrite(&x, sizeof(x), 1, fp)輸出,那麼就必須用fread(&x, sizeof(x), 1, fp)讀回來。如果不是這樣,那麼你就必須自己做scanf()或printf()函數的轉換動作,這個時候,就是你可以把文本文件中字符串"123456"解釋成(比如)整數123和456的時候,或者解釋成123456也行,都是你的自由。如果你明白這些原理,那麼在scanf("%d%d", &x, &y)遇到問題的時候,就不至於茫然不知所以然了。
如果你要加密,可以輸出fprintf("%d", 'A', fp)看看,把明文中的每個字符都用內碼輸出,那麼,你看到生成的文件就全是數字字符。讀回來,你自己想吧。明白上面所說的原理,你搞什麼手腳都可以,比如可以不用十進制,用二進制、十六進制,甚至二十進制也可以。不明白這些原理,你學一輩子C,不過色即是空。
fwrite()和fread()的優勢在哪裡呢?優勢是把內存直接複製出來或讀回去,完全不用轉換。比如對控制臺窗口整個屏幕,用這一條指令就可以把整塊屏幕或局部矩形方塊copy到硬盤上,不用理會都有什麼內容、什麼顏色的文字,完全複製,完全恢復,速度飛快(做遊戲時必用,橫移豎移畫面都是用這個技術做的,不會重新畫圖,從硬盤中讀入事先製作好的畫面就是了)。跟memcpy()或memmove()是一個東西。
[
本帖最后由 TonyDeng 于 2012-2-28 02:54 编辑 ]