[Powered by Google Translate] [ファイルI / O] [ジェイソン·ハーシュ、ハーバード大学] [これは、CS50.TV CS50です] 我々はファイルを考えるとき、何が頭に浮かぶことは、Microsoft Wordドキュメントです JPEG画像、またはMP3の曲、 そして我々はさまざまな方法でこれらのタイプのファイルのそれぞれと対話します。 たとえば、Word文書には、テキストを追加する JPEG画像との間に、我々は縁をトリミングしたり色をレタッチすることがあります。 まだフードの下で、我々のコンピュータ内のすべてのファイルは、より何もない 0と1の長いシーケンスより。 これは、ファイルを操作する特定のアプリケーション次第です この長いシーケンスを処理し、それをユーザーに提示する方法を決定する。 一方では、文書は、1バイトだけを見てもよい または8ゼロとものと、画面上のASCII文字を表示します。 一方、ビットマップイメージは、3バイトを見てもよい または24ゼロともの、 と3つの16進数値として解釈 赤、緑、青の値を表している 画像の1画素インチ どのような彼らは、彼らのコアで、画面上のように見えるかもしれません ファイルには、0と1のシーケンス以外の何物でもありません。 だからレッツに飛び込むと、我々は実際にこれらの0と1を操作する方法を見て への書き込みとファイルからの読み取りに来るとき。 私は、シンプルな3つのプロセスに分解することから始めます。 次に、私は、これらの3つの部分を示す2つのコード例に飛び込むでしょう。 最後に、私はプロセスを見直し、その最も重要な詳細の一部でしょう。 デスクトップ上に座って他のファイルと同様に、 最初に行うべきことは、それを開くことです。 C言語では、事前定義された構造体へのポインタを宣言することにより、これを行う それは、ディスク上のファイルを表します。 この関数呼び出しでは、我々はまた、我々はに書き込んだり、ファイルから読みたいかどうかを決定します。 次に、我々は、実際に読み取りと書き込みを行います。 我々はこの部分で使用できる特殊な機能がいくつかあり、 そしてそのほとんどがファイルを表す文字Fで始まる。 、あなたのコンピュータ上で開いているファイルの上隅にある小さな赤いXに似て、最後 我々は最終的な関数呼び出しを使用してファイルを閉じます。 今、我々は我々がやろうとしているという一般的な考えを持っていること、 コー​​ドの中にダイブしてみましょう。 このディレクトリには、我々は2つ​​のCファイルとそれに対応する実行可能ファイルを持っています。 タイプライターのプログラムは、1つのコマンドライン引数をとる 私たちが作成するドキュメントの名前。 このケースでは、我々はそれdoc.txt呼ぶことにします。 プログラムを実行し、いくつかの行を入力してみましょう。 こんにちは。私の名前はジェイソンです。 最後に、我々は "終了します"と入力します 我々は今、このディレクトリ内のすべてのファイルをリストする場合は、 私たちは、新しいドキュメントがdoc.txt呼ば存在していることを参照してください。 これは、このプログラムが作成したファイルです。 そしてもちろん、それはあまりにも0と1の長いシーケンス以外の何者でもありません。 我々はこの新しいファイルを開く場合、 我々は我々のプログラムに入力されたコードの3行を参照してください - こんにちは。月の名前はジェイソンです。 しかし、何が実際にtypewriter.cランが起こっているの? 我々にとって関心の最初の行が24行目です。 この行では、我々はファイルポインタを宣言します。 このポインタは、fopenを返す関数は、2つの引数をとります。 最初に適切な場合には、ファイル拡張子を含むファイル名です。 ファイル拡張子が最低レベルでファイルに影響を与えないことを思い出してください。 我々は常に0と1の長いシーケンスを扱っている。 しかし、それはファイルが解釈され、どのようなアプリケーションがそれらを開くために使用されるか影響しません。 fopenの第二引数は、単一の文字です それは、我々はファイルを開いた後に行うことを計画し何の略です。 W、R、およびA - この引数には3つのオプションがあります。 我々はファイルへの書き込みをしたいので、このケースではwを選択しました。 Rは、おそらく推測できるように、ファイルへの読み込みのためのものです。 とファイルに追加するにはです。 しばらくwとファイルへの書き込みに使用されるかもしれません両方、 wはファイルの先頭から書き込みを開始します 潜在的に以前に格納されているすべてのデータを上書きします。 デフォルトでは、それが存在しない場合、我々は、開いたファイル、 我々の現在の作業ディレクトリに作成されます。 しかし、我々は別の場所にあるファイルにアクセスしたり、作成したい場合は、 fopenの最初の引数に、 我々は、ファイル名に加えて、ファイルのパスを指定することもできます。 このプロセスの最初の部分は長いコードの1行のみであるが、 それはラインの別のセットを含めることが常に良い習慣 それは、ファイルが正常に開かれるか作成されたことを確実にするためにチェックします。 fopenはnullを返した場合、我々は、我々のプログラムを押し進めるのは嫌だ オペレーティングシステムのメモリが不足している場合、これは起こるかもしれません または我々は適切な権限を持っていなかった対象のディレクトリにファイルを開こうとする。 プロセスの第2部では、タイプライターのwhileループ内で行われます。 我々は、ユーザーからの入力を取得するCS50ライブラリ関数を使う そして、彼らはプログラムを終了しないかぎり 我々は、文字列を取る関数fputs関数を使用してファイルに書き込む。 fputs関数は、我々はファイルへの書き込みに使用できる多くの機能のひとつに過ぎません。 その他はfwriteの、fputcは、さらにfprintfのが含まれています。 かかわらず、我々が使用して終了し、特定の関数の、しかし、 それらのすべてを知る必要があり、その引数を経由して、 少なくとも2つのもの - 何が書かれており、それはどこに書き込む必要があるする必要があります。 私たちのケースでは、入力が記述する必要が文字列である とFPは、我々が書いている場所に私たちを導くのポインタです。 このプログラムでは、プロセスの第2部はむしろ簡単です。 我々は、単にユーザから文字列を取っている と少しツー無入力の検証やセキュリティチェックで我々のファイルに直接追加します。 しかし、多くの場合、第2部では、あなたのコードの大部分を占めるだろう。 最後に、パート3は、我々はファイルを閉じる58行、オンになっています。 ここに私達は私達の元のファイルポインタをfcloseをし、それを渡す呼び出します。 後続の行では、我々のプログラムの終了を知らせる、ゼロを返します。 そして、はい、パート3はそれと同じくらい簡単です。 のは、ファイルからの読み込みに移りましょう。 戻って我々のディレクトリに、我々はprinter.cと呼ばれるファイルを持っている。 それは、先ほど作成したファイルを使って実行してみましょう - doc.txt。 このプログラムは、その名が示すように、単にそれに渡されたファイルの内容をプリントアウトします。 そして我々はそれをそこに持っている。 コー​​ドの行数は、我々は前に入力したとdoc.txtに保存されていました。 こんにちは。私の名前はジェイソンです。 もしprinter.cに我々は、ダイビング、 我々は、多くのコードは、我々はちょうどtypewriter.cで通って歩い何に似ていることがわかります。 我々はファイルを開いた確かに22行、 我々は、ファイルを閉じて、39行目、 両方typewriter.cとほぼ同一であり、fopenの第2引数に保存します。 我々は、ファイルから読んでいるこの時間は、 ので、我々は、wの代わりにrを選びました。 したがって、のは、プロセスの後半部分に注目しましょう​​。 35行目では、私たちの4ループの中で第二の条件として、 我々は、fgetsのに電話をかける 前からfputs関数のコンパニオン機能。 我々は3つの引数を持っているこの時間。 最初の文字列が格納される文字の配列へのポインタです。 番目は読み込む文字の最大数です。 そして第三に、我々が作業しているとファイルへのポインタです。 あなたは、fgetsがnullを返したときにforループ終了することに気づくでしょう。 これが起こったかもしれない2つの理由があります。 まず、エラーが発生している可能性があります。 第二に、より可能性が高い、ファイルの終わりに達しました、それ以上の文字が読み込まれました。 あなたが迷っている場合では、2つの関数は、私たちに伝えることを可能にすることを存在しない その理由は、この特定のヌルポインタの原因となっています。 そして、驚くことではないが、彼らはファイルを扱うとしなければならないので、 文字Fでferror関数、feof関数start両方。 最後に、我々は結論する前に、ファイル関数の終わり約1簡単なメモ、 その、今述べたように、FEOFとして書かれています。 頻繁にあなた自身が徐々にファイルを通してあなたの方法を読むことながら、forループを使用して見つけることができます。 これらのファイルの最後に到達した後にこのようにして、これらのループを終了する方法が必要になります。 あなたのファイルポインタでfeofを呼び出し、それが真実かどうかをチェックする ちょうどそれをするだろう。 したがって、条件(!FEOF(FP))とwhileループが完全に適切な解決策のように思えるかもしれません。 しかし、我々は我々のテキストフ​​ァイルに残って1行を持っていると言う。 私たちは、whileループに入るだろうし、計画通りにすべてがうまくいく。 を介して次のラウンドでは、我々のプログラムは、FPのfeofは真であるかどうかをチェックします - しかし、これはここで理解するための重要なポイントである - それだけではまだ真実ではないだろう。 FEOFの目的はチェックしないようだからです read関数の次の呼び出しでは、ファイルの終わりにヒットする場合、 むしろファイルの終端に達したかどうかをチェックする。 この例の場合、 我々のファイルの最後の行を読んでいると、完全にスムーズに行く しかしプログラムはまだ我々は、ファイルの終わりをヒットしたことを知りません。 それはカウンターファイルの終わりをその1追加の読み取りを行うまではそうではありません。 したがって、正しい条件は次のようになります。 fgets関数とその3つの引数 - 出力、出力のサイズ、およびfp - その等しくないすべての値はnullです。 これは、我々はprinter.cで取ったアプローチです そしてこの場合、ループが終了した後、 あなたはこのループを抜けるための具体的な推論を、ユーザに通知するためには、feofまたはferrorを呼び出すことができます。 への書き込みとファイルからの読み取りを行うと、その最も基本的であり、 シンプルな3つのプロセス。 まず、ファイルを開きます。 第二に、我々は我々のファイルにいくつかのものを置くか、またはそれのうちいくつかのものを取る。 第三に、我々は、ファイルを閉じます。 最初と最後の部分は簡単です。 厄介な代物がどこにある真ん中の部分です。 とフードの下にかかわらず、我々は常に、0と1の長いシーケンスを扱っている 抽象化の層を追加するためにコーディングする際には役立ちますか それは、より密接に私たちが見慣れているものに似ている何かに順番に変わります。 たとえば、我々は、24ビットのビットマップファイルで作業している場合、 我々は、おそらくいつの3バイトの読み出しまたは書き込みを行うことでしょう。 その場合、それを定義し、適切に名前を付けるために理にかなっている 3バイト大きい構造体。 ファイルでの作業は複雑に見えるかもしれませんが、 それらを利用することが、私たちは、本当に驚くべき何かを行うことができます。 我々は、我々のプログラムの外の世界の状態を変更することができます 我々は、我々のプログラムの寿命を超えて住んでいる何かを作成することができます または私たちも、私たちのプログラム実行開始前に作成されたものを変更することができます。 ファイルと対話すると、C言語のプログラミングの本当に強力な一部である と私はあなたが来るためのコードでそれを使って作成しようとしているか見て興奮しています。 私の名前はジェイソン·ハーシュホーンです。これはCS50です。 [CS50.TV] [笑い] オーケー。一つは取る。ここに私達は行く。 我々はファイルを考えるとき - >>ああ、待って。申し訳ありません。 [笑い]オーケー。 ちょっとそこ。 我々は、ファイルを考えるとき - あなたがファイルを考えるとき - オーケー。準備ができたら教えてください。 ああ、素晴らしい。 プロンプターから読み取るのに思われるかもしれません - ない。私の悪い。