[Powered by Google Translate] [文件I / O] [賈森·赫塞豪恩,哈佛大學] 這是CS50,CS50.TV] 當我們想到一個文件,想到什麼是Microsoft Word文檔, JPEG圖像,或一首MP3歌曲, 和與每個這些不同的方式中的文件類型的交互。 例如,在Word文檔中添加文本 一個JPEG圖像時,我們可能會裁剪的邊緣或修飾的顏色。 然而,引擎蓋下的所有的文件在我們的電腦都更 比一個長序列的零和一。 它是由與該文件的特定的應用程序進行交互 決定如何處理這個長序列,並提交給用戶。 一方面,一個文件可能看起來只是一個字節, 或8個零和的,並顯示在屏幕上的一個ASCII字符。 另一方面,在3個字節,位圖圖像可能看起來 或24個0的, 並把它們解釋為3個十六進制數字 表示紅色,綠色,和藍色的值 在一個像素中的圖像。 無論它們看起來像在你的屏幕上,在他們的核心, 文件只不過是不是一個序列的零和一。 因此,讓我們的潛水和看我們如何實際操作這些零和一 當它涉及到從文件的寫入和讀取。 我將首先把它分解成三部分組成的一個簡單的過程。 接下來,我將深入到兩個代碼示例,說明這三個部分。 最後,我會檢討的過程和它的一些最重要的細節。 由於坐落在您的桌面上的任何文件, 做的第一件事是打開它。 在C語言中,我們做到這一點,聲明一個指針,指向一個預定義的結構 代表磁盤上的文件。 在這個函數中調用,我們還決定,我們是否要寫入或讀取的文件。 接下來,我們做了實際的閱讀和寫作。 有許多專門的功能,我們可以在這部分, 和幾乎所有的人都開始用字母“F”,表示文​​件。 最後,類似的小紅色的X在右上角的文件在您的計算機上打開, 最後一個函數調用,我們關閉文件。 現在,我們有一個總體思路,我們要做的是什麼, 讓我們深入到代碼。 在這個目錄中,我們有兩個C文件和其對應的可執行文件。 的的打字機程序需要一個命令行參數, 我們要創建的文件的名稱。 在這種情況下,我們叫它doc.txt的。 讓我們來運行程序並輸入幾行。 你好。我的名字是賈森。 最後,我們將鍵入“退出”。 如果我們現在在這個目錄中列出的所有文件, 我們看到一個新的文檔存在被稱為doc.txt。 剛創建的文件,這個程序。 當然,它也沒有什麼更比一個長序列的零和一。 如果我們打開這個新文件, 我們看到了3行代碼中,我們進入到我們的程序 - 你好。五月的名字是賈森。 但實際上上運行時typewriter.c? 我們感興趣的是第一行第24行。 在這條線,我們宣布我們的文件指針。 函數,返回this指針,FOPEN,需要兩個參數。 第一個是文件名,包括文件的擴展名(如適用)。 回想一下,不影響文件的文件擴展名的最低水平。 我們一直在處理一個長序列的零和一。 但它確實會影響文件的解釋和使用哪些應用程序打開。 的FOPEN的第二個參數是一個單一的字母 代表我們打開文件後,我們打算做什麼。 這種說法有三個選項 - W,R,和A. 我們選擇w在這種情況下,因為我們要寫入的文件。 R,你可能已經猜到了,是閱讀文件。 一個是附加到文件。 雖然兩者w和可用於寫入文件, w將開始編寫的文件從一開始就 和潛在的覆蓋任何先前已被存儲的數據。 默認情況下,我們打開的文件,如果它已經不存在, 是建立在我們的當前工作目錄。 但是,如果我們要訪問或創建一個文件在不同的位置, 在第一個參數的FOPEN, 除了文件名中,我們可以指定一個文件路徑。 雖然這個過程的第一部分是只有一行代碼長, 它總是個好習慣,另一組線 檢查,以確保該文件被成功打開或創建。 如果FOPEN返回null,我們不希望我們的計劃,開拓進取, 這可能發生,如果操作系統的內存 或者,如果我們試圖打開一個文件,一個目錄,而我們沒有適當的權限。 第二部分的過程中發生在打字機的while循環。 我們使用CS50的庫函數來獲取來自用戶的輸入, 並假設他們不想退出程序, 我們使用的功能FPUTS的的字符串,並寫入的文件。 FPUTS是唯一的眾多功能之一,我們可以用它來寫的文件。 其他包括的FWRITE,的fputc,甚至fprintf。 不管特定的功能,我們最終使用,雖然, 所有的人都需要知道,通過他們的觀點, 至少有兩件事情 - 需要寫什麼,它需要被寫入到。 在我們的例子中,輸入的字符串,需要編寫 計劃生育是我們的地方,我們正在編寫的指針。 在這個程序中,第二部分的過程是相當簡單的。 我們只是一個來自用戶的字符串 並直接將其添加到我們的文件,小到沒有輸入驗證或安全檢查。 然而,通常情況下,第二部分將佔用大量的代碼。 最後,第三部分是在第58行,我們關閉文件。 在這裡,我們調用fclose,並通過它我們原來的文件指針。 在隨後的行中,我們返回零,我們的節目結束的信號。 是的,第三部分是那樣簡單。 讓我們從文件讀取。 早在我們的目錄中,我們有一個名為printer.c。 讓我們運行它與我們剛創建的文件 - doc.txt。 這個程序,顧名思義,會簡單地打印出的文件的內容傳遞給它。 在那裡,我們有它。 該行代碼中,我們輸入了和保存在doc.txt。 你好。我的名字是賈森。 如果我們深入printer.c, 我們看到了很多的代碼看起來類似於我們剛剛走過的typewriter.c。 事實上,第22行,在這裡我們打開的文件, 第39行,我們關閉了文件, 既是幾乎相同的typewriter.c,保存為fopen的第二個參數。 這一次我們從文件中讀取, 因此我們選擇了R替代的W。 因此,讓我們關注的第二個過程的一部分。 在第35行中,在我們的4迴路的第二個條件, 我們對fgets撥打電話, 的伴侶功能從之前到FPUTS。 這一次,我們有三個參數。 首先是指針的數組的字符的字符串將被存儲。 第二個是要讀取的最大字符數。 第三個是我們工作的文件指針。 你會發現,在for循環結束時,與fgets返回null。 有兩個原因,這可能發生。 首先,可能發生錯誤。 其次,更可能的文件,最終達成,並沒有更多的字符讀。 如果你想知道,有兩個功能,使我們能夠告訴 其中的原因是這個特殊的空指針的原因。 而且,這並不奇怪,因為他們所要做的工作的文件, FERROR功能和的FEOF的功能開始用字母“F”。 最後,在一個快速的注意事項有關的文件的功能,我們可以得出結論, 其中,剛才提到的,寫的是為FEOF。 通常情況下,你會發現自己使用whil​​e和for循環,逐步讀取文件的通過自己的方式。 因此,你需要的方式來結束這些循環後,到達終點這些文件。 ,調用FEOF上的文件指針和檢查,看它是否是真實的 做到這一點。 因此,一個while循環的條件(文件指針(FP))可能看起來像一個完全合適的解決方案。 不過,說我們有一個線留在我們的文本文件。 我們將進入我們的while循環,按計劃,一切都會迎刃而解。 通過下一輪,我們的計劃將檢查,如果FEOF的FP是真正的, 但是 - 這是了解這裡的關鍵點 - 它不會是真實的,只是還沒有。 這是因為是不檢查的目的FEOF 如果讀出功能的下一個呼叫將命中的文件的結尾, 而是,以檢查是否已達到了該文件的結束。 在本實施例的情況下, 閱讀我們的文件的最後一行是完全順利, 但該方案還不知道,我們已經打到最後我們的文件。 這不是一個額外的讀出,直到它,計數器結束的文件。 因此,正確的條件將以下內容: fgets和它的三個參數 - 輸出,輸出的大小,和FP - 和所有的,不等於空。 這是我們採取的方法在printer.c, 和在這種情況下,循環退出時,後 你可以調用的feof或FERROR退出這個循環的具體理由通知用戶。 寫入和讀取文件,在其最基本的, 三部分組成的一個簡單的過程。 首先,我們打開該文件。 第二,我們把一些東西到我們的文件或採取了一些東西的。 第三,我們關閉該文件。 的第一和最後的部分很容易的。 中間部分是棘手的問題所在。 雖然引擎蓋下的,我們一直在處理一個長序列的零和一, 它添加了一個抽象層編碼時 將序列更接近於我們已經習慣看到的東西。 例如,如果我們正在使用一個24位位圖文件, 我們很可能會被讀​​取或寫入三個字節的時間。 在這種情況下,這將是有意義的定義和適當的命名 一個結構,是3個字節。 雖然工作的文件可能看起來很複雜, 利用它們,可以讓我們做一些真正了不起的。 我們的節目外,我們可以改變世界的狀態, 我們可以創造一些生活以外的生活我們的計劃, 我們之前創建的程序開始運行,甚至可以改變​​的東西。 互動的文件是一個真正強大的部分用C語言編程 我很高興能看到你要創建它的代碼來。 我的名字是賈森·赫塞豪恩。這是CS50。 [CS50.TV] [笑] 好吧。一個需要。在這裡,我們走了。 當我們想到的一個文件 - “”哦,等等。抱歉。 [笑]好吧。 嘿。 當我們想到一個文件 - 當你想到一個文件 - 好。告訴我,當你準備好了。 哦,太棒了。 雖然從提詞器讀取似乎是 - 沒有。我的壞。