1 00:00:00,000 --> 00:00:02,000 [Powered by Google Translate] [ファイルI / O] 2 00:00:02,000 --> 00:00:04,000 [ジェイソン·ハーシュ、ハーバード大学] 3 00:00:04,000 --> 00:00:07,000 [これは、CS50.TV CS50です] 4 00:00:07,000 --> 00:00:11,000 我々はファイルを考えるとき、何が頭に浮かぶことは、Microsoft Wordドキュメントです 5 00:00:11,000 --> 00:00:14,000 JPEG画像、またはMP3の曲、 6 00:00:14,000 --> 00:00:17,000 そして我々はさまざまな方法でこれらのタイプのファイルのそれぞれと対話します。 7 00:00:17,000 --> 00:00:20,000 たとえば、Word文書には、テキストを追加する 8 00:00:20,000 --> 00:00:24,000 JPEG画像との間に、我々は縁をトリミングしたり色をレタッチすることがあります。 9 00:00:24,000 --> 00:00:28,000 まだフードの下で、我々のコンピュータ内のすべてのファイルは、より何もない 10 00:00:28,000 --> 00:00:31,000 0と1の長いシーケンスより。 11 00:00:31,000 --> 00:00:33,000 これは、ファイルを操作する特定のアプリケーション次第です 12 00:00:33,000 --> 00:00:38,000 この長いシーケンスを処理し、それをユーザーに提示する方法を決定する。 13 00:00:38,000 --> 00:00:41,000 一方では、文書は、1バイトだけを見てもよい 14 00:00:41,000 --> 00:00:45,000 または8ゼロとものと、画面上のASCII文字を表示します。 15 00:00:45,000 --> 00:00:48,000 一方、ビットマップイメージは、3バイトを見てもよい 16 00:00:48,000 --> 00:00:50,000 または24ゼロともの、 17 00:00:50,000 --> 00:00:53,000 と3つの16進数値として解釈 18 00:00:53,000 --> 00:00:56,000 赤、緑、青の値を表している 19 00:00:56,000 --> 00:00:58,000 画像の1画素インチ 20 00:00:58,000 --> 00:01:01,000 どのような彼らは、彼らのコアで、画面上のように見えるかもしれません 21 00:01:01,000 --> 00:01:05,000 ファイルには、0と1のシーケンス以外の何物でもありません。 22 00:01:05,000 --> 00:01:08,000 だからレッツに飛び込むと、我々は実際にこれらの0と1を操作する方法を見て 23 00:01:08,000 --> 00:01:12,000 への書き込みとファイルからの読み取りに来るとき。 24 00:01:12,000 --> 00:01:15,000 >> 私は、シンプルな3つのプロセスに分解することから始めます。 25 00:01:15,000 --> 00:01:19,000 次に、私は、これらの3つの部分を示す2つのコード例に飛び込むでしょう。 26 00:01:19,000 --> 00:01:23,000 最後に、私はプロセスを見直し、その最も重要な詳細の一部でしょう。 27 00:01:23,000 --> 00:01:25,000 デスクトップ上に座って他のファイルと同様に、 28 00:01:25,000 --> 00:01:28,000 最初に行うべきことは、それを開くことです。 29 00:01:28,000 --> 00:01:31,000 C言語では、事前定義された構造体へのポインタを宣言することにより、これを行う 30 00:01:31,000 --> 00:01:33,000 それは、ディスク上のファイルを表します。 31 00:01:33,000 --> 00:01:38,460 この関数呼び出しでは、我々はまた、我々はに書き込んだり、ファイルから読みたいかどうかを決定します。 32 00:01:38,460 --> 00:01:41,660 次に、我々は、実際に読み取りと書き込みを行います。 33 00:01:41,660 --> 00:01:44,800 我々はこの部分で使用できる特殊な機能がいくつかあり、 34 00:01:44,800 --> 00:01:48,790 そしてそのほとんどがファイルを表す文字Fで始まる。 35 00:01:48,790 --> 00:01:53,560 、あなたのコンピュータ上で開いているファイルの上隅にある小さな赤いXに似て、最後 36 00:01:53,560 --> 00:01:56,680 我々は最終的な関数呼び出しを使用してファイルを閉じます。 37 00:01:56,680 --> 00:01:59,540 今、我々は我々がやろうとしているという一般的な考えを持っていること、 38 00:01:59,540 --> 00:02:02,000 コー​​ドの中にダイブしてみましょう。 39 00:02:02,000 --> 00:02:06,100 >> このディレクトリには、我々は2つ​​のCファイルとそれに対応する実行可能ファイルを持っています。 40 00:02:06,100 --> 00:02:09,710 タイプライターのプログラムは、1つのコマンドライン引数をとる 41 00:02:09,710 --> 00:02:12,060 私たちが作成するドキュメントの名前。 42 00:02:12,060 --> 00:02:16,160 このケースでは、我々はそれdoc.txt呼ぶことにします。 43 00:02:16,160 --> 00:02:19,080 プログラムを実行し、いくつかの行を入力してみましょう。 44 00:02:19,080 --> 00:02:23,660 こんにちは。私の名前はジェイソンです。 45 00:02:23,660 --> 00:02:26,710 最後に、我々は "終了します"と入力します 46 00:02:26,710 --> 00:02:29,720 我々は今、このディレクトリ内のすべてのファイルをリストする場合は、 47 00:02:29,720 --> 00:02:33,770 私たちは、新しいドキュメントがdoc.txt呼ば存在していることを参照してください。 48 00:02:34,190 --> 00:02:36,110 これは、このプログラムが作成したファイルです。 49 00:02:36,110 --> 00:02:40,520 そしてもちろん、それはあまりにも0と1の長いシーケンス以外の何者でもありません。 50 00:02:41,100 --> 00:02:43,260 我々はこの新しいファイルを開く場合、 51 00:02:43,260 --> 00:02:45,870 我々は我々のプログラムに入力されたコードの3行を参照してください - 52 00:02:46,060 --> 00:02:49,060 こんにちは。月の名前はジェイソンです。 53 00:02:49,580 --> 00:02:52,090 しかし、何が実際にtypewriter.cランが起こっているの? 54 00:02:52,810 --> 00:02:55,520 我々にとって関心の最初の行が24行目です。 55 00:02:55,560 --> 00:02:58,490 この行では、我々はファイルポインタを宣言します。 56 00:02:59,080 --> 00:03:03,140 このポインタは、fopenを返す関数は、2つの引数をとります。 57 00:03:03,140 --> 00:03:07,440 最初に適切な場合には、ファイル拡張子を含むファイル名です。 58 00:03:07,440 --> 00:03:10,980 ファイル拡張子が最低レベルでファイルに影響を与えないことを思い出してください。 59 00:03:10,980 --> 00:03:14,640 我々は常に0と1の長いシーケンスを扱っている。 60 00:03:14,640 --> 00:03:19,630 しかし、それはファイルが解釈され、どのようなアプリケーションがそれらを開くために使用されるか影響しません。 61 00:03:19,630 --> 00:03:22,290 fopenの第二引数は、単一の文字です 62 00:03:22,290 --> 00:03:25,300 それは、我々はファイルを開いた後に行うことを計画し何の略です。 63 00:03:25,300 --> 00:03:30,630 W、R、およびA - この引数には3つのオプションがあります。 64 00:03:30,630 --> 00:03:34,900 我々はファイルへの書き込みをしたいので、このケースではwを選択しました。 65 00:03:34,900 --> 00:03:38,820 Rは、おそらく推測できるように、ファイルへの読み込みのためのものです。 66 00:03:38,820 --> 00:03:41,760 とファイルに追加するにはです。 67 00:03:41,760 --> 00:03:44,960 しばらくwとファイルへの書き込みに使用されるかもしれません両方、 68 00:03:44,960 --> 00:03:47,460 wはファイルの先頭から書き込みを開始します 69 00:03:47,460 --> 00:03:50,810 潜在的に以前に格納されているすべてのデータを上書きします。 70 00:03:50,810 --> 00:03:54,070 デフォルトでは、それが存在しない場合、我々は、開いたファイル、 71 00:03:54,070 --> 00:03:57,180 我々の現在の作業ディレクトリに作成されます。 72 00:03:57,180 --> 00:04:00,540 しかし、我々は別の場所にあるファイルにアクセスしたり、作成したい場合は、 73 00:04:00,540 --> 00:04:02,650 fopenの最初の引数に、 74 00:04:02,650 --> 00:04:05,840 我々は、ファイル名に加えて、ファイルのパスを指定することもできます。 75 00:04:05,840 --> 00:04:09,490 このプロセスの最初の部分は長いコードの1行のみであるが、 76 00:04:09,490 --> 00:04:12,350 それはラインの別のセットを含めることが常に良い習慣 77 00:04:12,350 --> 00:04:15,930 それは、ファイルが正常に開かれるか作成されたことを確実にするためにチェックします。 78 00:04:15,930 --> 00:04:20,300 fopenはnullを返した場合、我々は、我々のプログラムを押し進めるのは嫌だ 79 00:04:20,300 --> 00:04:23,270 オペレーティングシステムのメモリが不足している場合、これは起こるかもしれません 80 00:04:23,270 --> 00:04:27,940 または我々は適切な権限を持っていなかった対象のディレクトリにファイルを開こうとする。 81 00:04:27,940 --> 00:04:31,780 >> プロセスの第2部では、タイプライターのwhileループ内で行われます。 82 00:04:31,780 --> 00:04:35,000 我々は、ユーザーからの入力を取得するCS50ライブラリ関数を使う 83 00:04:35,000 --> 00:04:37,190 そして、彼らはプログラムを終了しないかぎり 84 00:04:37,190 --> 00:04:41,940 我々は、文字列を取る関数fputs関数を使用してファイルに書き込む。 85 00:04:41,940 --> 00:04:46,700 fputs関数は、我々はファイルへの書き込みに使用できる多くの機能のひとつに過ぎません。 86 00:04:46,700 --> 00:04:51,920 その他はfwriteの、fputcは、さらにfprintfのが含まれています。 87 00:04:51,920 --> 00:04:54,840 かかわらず、我々が使用して終了し、特定の関数の、しかし、 88 00:04:54,840 --> 00:04:57,480 それらのすべてを知る必要があり、その引数を経由して、 89 00:04:57,480 --> 00:04:59,670 少なくとも2つのもの - 90 00:04:59,670 --> 00:05:03,140 何が書かれており、それはどこに書き込む必要があるする必要があります。 91 00:05:03,140 --> 00:05:07,240 私たちのケースでは、入力が記述する必要が文字列である 92 00:05:07,240 --> 00:05:11,290 とFPは、我々が書いている場所に私たちを導くのポインタです。 93 00:05:11,290 --> 00:05:15,330 このプログラムでは、プロセスの第2部はむしろ簡単です。 94 00:05:15,330 --> 00:05:17,360 我々は、単にユーザから文字列を取っている 95 00:05:17,360 --> 00:05:22,120 と少しツー無入力の検証やセキュリティチェックで我々のファイルに直接追加します。 96 00:05:22,120 --> 00:05:26,160 しかし、多くの場合、第2部では、あなたのコードの大部分を占めるだろう。 97 00:05:26,160 --> 00:05:30,580 最後に、パート3は、我々はファイルを閉じる58行、オンになっています。 98 00:05:30,580 --> 00:05:34,860 ここに私達は私達の元のファイルポインタをfcloseをし、それを渡す呼び出します。 99 00:05:34,860 --> 00:05:39,500 後続の行では、我々のプログラムの終了を知らせる、ゼロを返します。 100 00:05:39,500 --> 00:05:42,630 そして、はい、パート3はそれと同じくらい簡単です。 101 00:05:42,630 --> 00:05:45,260 >> のは、ファイルからの読み込みに移りましょう。 102 00:05:45,260 --> 00:05:48,220 戻って我々のディレクトリに、我々はprinter.cと呼ばれるファイルを持っている。 103 00:05:48,220 --> 00:05:50,910 それは、先ほど作成したファイルを使って実行してみましょう - 104 00:05:50,910 --> 00:05:53,350 doc.txt。 105 00:05:53,350 --> 00:05:58,150 このプログラムは、その名が示すように、単にそれに渡されたファイルの内容をプリントアウトします。 106 00:05:58,150 --> 00:06:00,230 そして我々はそれをそこに持っている。 107 00:06:00,230 --> 00:06:03,780 コー​​ドの行数は、我々は前に入力したとdoc.txtに保存されていました。 108 00:06:03,780 --> 00:06:06,980 こんにちは。私の名前はジェイソンです。 109 00:06:06,980 --> 00:06:09,120 もしprinter.cに我々は、ダイビング、 110 00:06:09,120 --> 00:06:13,570 我々は、多くのコードは、我々はちょうどtypewriter.cで通って歩い何に似ていることがわかります。 111 00:06:13,570 --> 00:06:16,720 我々はファイルを開いた確かに22行、 112 00:06:16,720 --> 00:06:19,220 我々は、ファイルを閉じて、39行目、 113 00:06:19,220 --> 00:06:23,890 両方typewriter.cとほぼ同一であり、fopenの第2引数に保存します。 114 00:06:23,890 --> 00:06:26,510 我々は、ファイルから読んでいるこの時間は、 115 00:06:26,510 --> 00:06:29,040 ので、我々は、wの代わりにrを選びました。 116 00:06:29,040 --> 00:06:31,950 したがって、のは、プロセスの後半部分に注目しましょう​​。 117 00:06:31,950 --> 00:06:36,060 35行目では、私たちの4ループの中で第二の条件として、 118 00:06:36,060 --> 00:06:38,590 我々は、fgetsのに電話をかける 119 00:06:38,590 --> 00:06:42,190 前からfputs関数のコンパニオン機能。 120 00:06:42,190 --> 00:06:44,660 我々は3つの引数を持っているこの時間。 121 00:06:44,660 --> 00:06:48,810 最初の文字列が格納される文字の配列へのポインタです。 122 00:06:48,810 --> 00:06:52,670 番目は読み込む文字の最大数です。 123 00:06:52,670 --> 00:06:56,010 そして第三に、我々が作業しているとファイルへのポインタです。 124 00:06:56,010 --> 00:07:00,780 あなたは、fgetsがnullを返したときにforループ終了することに気づくでしょう。 125 00:07:00,780 --> 00:07:02,940 これが起こったかもしれない2つの理由があります。 126 00:07:02,940 --> 00:07:05,380 まず、エラーが発生している可能性があります。 127 00:07:05,380 --> 00:07:10,740 第二に、より可能性が高い、ファイルの終わりに達しました、それ以上の文字が読み込まれました。 128 00:07:10,740 --> 00:07:14,040 あなたが迷っている場合では、2つの関数は、私たちに伝えることを可能にすることを存在しない 129 00:07:14,040 --> 00:07:17,160 その理由は、この特定のヌルポインタの原因となっています。 130 00:07:17,160 --> 00:07:21,090 そして、驚くことではないが、彼らはファイルを扱うとしなければならないので、 131 00:07:21,090 --> 00:07:26,940 文字Fでferror関数、feof関数start両方。 132 00:07:26,940 --> 00:07:32,130 >> 最後に、我々は結論する前に、ファイル関数の終わり約1簡単なメモ、 133 00:07:32,130 --> 00:07:36,690 その、今述べたように、FEOFとして書かれています。 134 00:07:36,690 --> 00:07:41,550 頻繁にあなた自身が徐々にファイルを通してあなたの方法を読むことながら、forループを使用して見つけることができます。 135 00:07:41,550 --> 00:07:45,790 これらのファイルの最後に到達した後にこのようにして、これらのループを終了する方法が必要になります。 136 00:07:45,790 --> 00:07:50,510 あなたのファイルポインタでfeofを呼び出し、それが真実かどうかをチェックする 137 00:07:50,510 --> 00:07:52,310 ちょうどそれをするだろう。 138 00:07:52,310 --> 00:07:59,820 したがって、条件(!FEOF(FP))とwhileループが完全に適切な解決策のように思えるかもしれません。 139 00:07:59,820 --> 00:08:03,770 しかし、我々は我々のテキストフ​​ァイルに残って1行を持っていると言う。 140 00:08:03,770 --> 00:08:07,130 私たちは、whileループに入るだろうし、計画通りにすべてがうまくいく。 141 00:08:07,130 --> 00:08:12,750 を介して次のラウンドでは、我々のプログラムは、FPのfeofは真であるかどうかをチェックします 142 00:08:12,750 --> 00:08:15,430 - しかし、これはここで理解するための重要なポイントである - 143 00:08:15,430 --> 00:08:17,770 それだけではまだ真実ではないだろう。 144 00:08:17,770 --> 00:08:21,110 FEOFの目的はチェックしないようだからです 145 00:08:21,110 --> 00:08:24,400 read関数の次の呼び出しでは、ファイルの終わりにヒットする場合、 146 00:08:24,400 --> 00:08:28,190 むしろファイルの終端に達したかどうかをチェックする。 147 00:08:28,190 --> 00:08:30,140 この例の場合、 148 00:08:30,140 --> 00:08:32,780 我々のファイルの最後の行を読んでいると、完全にスムーズに行く 149 00:08:32,780 --> 00:08:36,210 しかしプログラムはまだ我々は、ファイルの終わりをヒットしたことを知りません。 150 00:08:36,210 --> 00:08:40,549 それはカウンターファイルの終わりをその1追加の読み取りを行うまではそうではありません。 151 00:08:40,549 --> 00:08:43,210 したがって、正しい条件は次のようになります。 152 00:08:43,210 --> 00:08:49,330 fgets関数とその3つの引数 - 出力、出力のサイズ、およびfp - 153 00:08:49,330 --> 00:08:52,570 その等しくないすべての値はnullです。 154 00:08:52,570 --> 00:08:55,260 これは、我々はprinter.cで取ったアプローチです 155 00:08:55,260 --> 00:08:57,890 そしてこの場合、ループが終了した後、 156 00:08:57,890 --> 00:09:04,290 あなたはこのループを抜けるための具体的な推論を、ユーザに通知するためには、feofまたはferrorを呼び出すことができます。 157 00:09:04,290 --> 00:09:08,100 >> への書き込みとファイルからの読み取りを行うと、その最も基本的であり、 158 00:09:08,100 --> 00:09:10,150 シンプルな3つのプロセス。 159 00:09:10,150 --> 00:09:12,530 まず、ファイルを開きます。 160 00:09:12,530 --> 00:09:16,740 第二に、我々は我々のファイルにいくつかのものを置くか、またはそれのうちいくつかのものを取る。 161 00:09:16,740 --> 00:09:19,200 第三に、我々は、ファイルを閉じます。 162 00:09:19,200 --> 00:09:21,170 最初と最後の部分は簡単です。 163 00:09:21,170 --> 00:09:23,920 厄介な代物がどこにある真ん中の部分です。 164 00:09:23,920 --> 00:09:27,760 とフードの下にかかわらず、我々は常に、0と1の長いシーケンスを扱っている 165 00:09:27,760 --> 00:09:30,710 抽象化の層を追加するためにコーディングする際には役立ちますか 166 00:09:30,710 --> 00:09:35,350 それは、より密接に私たちが見慣れているものに似ている何かに順番に変わります。 167 00:09:35,350 --> 00:09:39,570 たとえば、我々は、24ビットのビットマップファイルで作業している場合、 168 00:09:39,570 --> 00:09:43,290 我々は、おそらくいつの3バイトの読み出しまたは書き込みを行うことでしょう。 169 00:09:43,290 --> 00:09:46,450 その場合、それを定義し、適切に名前を付けるために理にかなっている 170 00:09:46,450 --> 00:09:48,980 3バイト大きい構造体。 171 00:09:48,980 --> 00:09:51,410 >> ファイルでの作業は複雑に見えるかもしれませんが、 172 00:09:51,410 --> 00:09:54,530 それらを利用することが、私たちは、本当に驚くべき何かを行うことができます。 173 00:09:54,530 --> 00:09:58,880 我々は、我々のプログラムの外の世界の状態を変更することができます 174 00:09:58,880 --> 00:10:01,730 我々は、我々のプログラムの寿命を超えて住んでいる何かを作成することができます 175 00:10:01,730 --> 00:10:07,190 または私たちも、私たちのプログラム実行開始前に作成されたものを変更することができます。 176 00:10:07,190 --> 00:10:11,210 ファイルと対話すると、C言語のプログラミングの本当に強力な一部である 177 00:10:11,210 --> 00:10:15,300 と私はあなたが来るためのコードでそれを使って作成しようとしているか見て興奮しています。 178 00:10:15,300 --> 00:10:19,770 私の名前はジェイソン·ハーシュホーンです。これはCS50です。 179 00:10:19,770 --> 00:10:21,770 [CS50.TV] 180 00:10:21,770 --> 00:10:25,940 >> [笑い] 181 00:10:25,940 --> 00:10:29,330 オーケー。一つは取る。ここに私達は行く。 182 00:10:49,000 --> 00:10:52,140 我々はファイルを考えるとき - >>ああ、待って。申し訳ありません。 183 00:10:52,140 --> 00:10:56,800 [笑い]オーケー。 184 00:11:06,620 --> 00:11:09,970 ちょっとそこ。 185 00:11:13,670 --> 00:11:16,310 我々は、ファイルを考えるとき - 186 00:11:17,610 --> 00:11:20,710 あなたがファイルを考えるとき - オーケー。準備ができたら教えてください。 187 00:11:20,710 --> 00:11:22,520 ああ、素晴らしい。 188 00:11:22,520 --> 00:11:26,180 プロンプターから読み取るのに思われるかもしれません - ない。私の悪い。