您描述的問題是(很常見的很不常見的)的錯誤和誤解。讓我試着詳細描述正在發生的事情,希望您花時間閱讀所有的材料:它很長,但這些都是任何程序員都應該掌握的非常重要的基礎知識。請不要絕望,如果你不完全瞭解它的全部內容:只是試着玩弄它,回來一兩個星期,練習,看看會發生什麼:)
這些概念之間有一個至關重要的區別字符編碼和字符集合。除非你真的瞭解這種差異,否則你將永遠無法真正瞭解發生了什麼。 Joel Spolsky(Stackoverflow的創始人之一,想起它)寫了一篇文章,解釋了前一段時間的差異:The Absolute Minimum Every Software Developer Absolutely, Positively Must Know About Unicode and Character Sets (No Excuses!)。在繼續閱讀本書之前,在繼續編程之前,甚至閱讀它。老實說,閱讀它,理解它:標題是毫不誇張的。你必須絕對知道這個東西。
之後,讓我們繼續:
當C程序運行時,是應該的存儲空間來保存類型爲「字符」中包含的價值,就像任何其他的存儲位置,1的序列和零。一個變量的「類型」只對編譯器有意義,對正在運行的程序來說只是看到一個和零,並且不知道更多。換句話說:你通常認爲在某處存在一個「字母」(來自字符設置爲)的內容的實際存在位序列(來自字符編碼)的元素。
每個編譯器都可以自由使用他們希望在內存中表示字符的任何編碼。因此,它可以自由地在內部表示我們稱之爲「新行」的任何數字。例如,假設我編寫了一個編譯器,我可以同意我自己,每次我想在內部存儲一個「換行符」時,我將它存儲爲數字6(6),二進制文件只有0x6(或者二進制數爲110)。
請注意,這與數據的「類型」無關:您的操作不知道,也不在乎。它不知道任何有關字符集的內容,它並不在乎:它只是看到一系列從零開始並將其複製到文件中的序列。
以「二進制」模式打開文件實際上是處理新手程序員期望的文件的正常直觀方式:將指定的內存位置一對一地複製到文件中。如果您編寫一個用於存放編譯器決定存儲爲類型「char」的變量的內存位置,則這些值將一對一地寫入該文件。除非你知道編譯器如何在內部存儲值(它與一個換行符關聯的值,以字母「a」,「b」等),這是無意義的。把這個和Joel的類似點比較一下,這個關於一個文本文件無用而不知道它的編碼是什麼的:同樣的事情。在「文本」模式下打開文件幾乎等於二進制模式,只有一個(且只有一個)差異:任何時候寫入的值都等於編譯器對換行符使用INTERNALLY的值(6,in我們的情況),它寫了一些與文件不同的東西:不是那個值,但是不管你所在的操作系統是否被認爲是換行符。在Windows上,這是兩個字節(在Windows上是13和10,或0x0d 0x0a)。再次注意,如果你不知道編譯器對其他字符的內部表示的選擇,這仍然是無意義的。
請注意,在文本模式下編寫除編譯器指定爲字符的數據之外的任何內容都非常明顯:在我們的例子中,6可能恰好在您的值之中正在寫作,在這種情況下,輸出的改變方式絕對不是我們的意思。 (Un)幸運的是,大多數(所有?)編譯器實際上對字符使用相同的內部表示形式:這種表示形式是US-ASCII,它是所有默認值的母親。這就是您可以在程序中爲某個文件編寫一些「字符」的原因,可以使用任意隨機編譯器進行編譯,然後使用文本編輯器打開它們:它們都使用/理解US-ASCII,並且它正常工作。
好的,現在將其連接到您的示例:爲什麼在編寫二進制模式和文本模式下的「測試」之間沒有區別? 因爲「測試」中沒有換行符,所以!
當你「打開文件」,然後「看到」字符是什麼意思?這意味着你用來檢查該文件中1和0序列的程序(因爲硬盤上的所有內容都是1和0)決定將其解釋爲US-ASCII,而這正好是你的編譯器決定編碼的內容它的內存中的字符串。加分:編寫一個從文件中讀入1和0的程序到存儲器並打印每個BIT(有多個位組成一個字節,提取它們,你需要知道'按位'操作符技巧,谷歌! )作爲「1」或「0」給用戶。請注意,「1」是字符1,即您選擇的字符集中的點,因此您的程序必須佔用一位(數字1或0)並將其轉換爲表示字符1或0所需的位序列編碼,終端模擬器使用你正在查看標準的程序哦,我的上帝。好消息是,通過假定US-ASCII處處可以採取很多捷徑。這個程序會告訴你你想要什麼:你的編譯器用來在內部表示「測試」的序列和零。
這對於新手來說真的很艱鉅,我知道花了很長時間才知道是是字符集和編碼之間的區別,更不用說所有這些如何工作了。希望我沒有激勵你,如果我這樣做,只要記住你永遠不會失去你已有的知識,只有獲得它(好吧,不總是正確的:P)。在生活中,聲明提出的問題超出了它的回答,蘇格拉底知道這一點,他的智慧在2.4k年後無縫適用於現代技術。
祝你好運,不要猶豫,繼續問。對於其他讀者:如果您發現錯誤,歡迎您改進本文。
Hraban
是告訴你,「二進制保存文件可能是較小的」,例如人,大概嚴重誤解了這些基礎知識。除非他保存數據之前是指壓縮數據,在這種情況下,他只是使用一個混淆詞(「二進制」)來表示「壓縮」。
「告訴操作系統的東西」就是通常所說的系統調用。
這是C而不是C++,除了你的一個std ::系統調用 – 2011-04-13 11:29:03
好吧,C然後。但爲什麼它不起作用? – Datoxalas 2011-04-13 11:30:44