[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]
>> [笑]
好吧。一個需要。在這裡，我們走了。
當我們想到的一個文件 - “”哦，等等。抱歉。
[笑]好吧。
嘿。
當我們想到一個文件 -
當你想到一個文件 - 好。告訴我，當你準備好了。
哦，太棒了。
雖然從提詞器讀取似乎是 - 沒有。我的壞。