バイナリファイル操作 

右の画像ファイルの16進ダンプ内容を、以下に示します。
ファイル名は『red128.gif』です。

C言語では、1byteの入力関数用として、fgetc関数が標準関数として用意されています。
この関数は、FILE *型の入力ストリームを引数にして、それから入力した1byteを返します。 ただしエラー時は、-1のEOFを返します。
つまり、fgetc引数にfopenでオープンしたポインタ(FILE *型)を指定すると ファイル操作ができます。
上記画像ファイルの『red128.gif』をオープンして、 そのデータの先頭から各バイトを順次に16進数で画面に表示するプログラムを以下に示します。

#include <stdio.h>
main(int argc, char *argv[])
{
	char *p_file;		/* ファイル名管理用*/
	FILE *fpr;		/* 読み取りストリーム管理用FILE Pointer by Read */
	int pos = 0;		/* ファイル内位置管理用(position )*/  	
	int c; 			/* fgetの戻り値記憶用*/

	p_file = argv[1];	/* コマンドラインパラメタより、ファイル名を設定 */
	fpr=fopen( p_file , "r" );/* ファイル読み取りモードでオープン*/

	/* ファイルからの読み取り繰り返し*/
	while( (c=fgetc(fpr)) != EOF ){
		if(pos % 16 == 0){
			printf("\n%04X ", pos);
		}
		printf("%02X ", c);/* 表示 */
		pos++;
	}
	fclose(fpr); /* ファイルクローズ*/
}

このプログラムの実行結果は、次のようになります。
これは、ファイルの読み取りが途中で終了するからです。
上記の"r"をクリックして、"rb"へ変更することで、
最後まで正しく読み込めるプログラムになります。

これは、fopenの第2引数の指定によりテキストモード("r")バイナリモード("rb")のアクセス方法があり、 それによりfgetcやfputcなどの挙動が変るためです。
(これは、Windowsシステムの特有の区別で、unix関連は全てバイナリモードで、区別していません。)
バイナリモード時は、unix と同じで全ての1byeを単純に入出力します。

対して、 テキストモードの場合は次のように変ります。
'\n' つまり、0xA0 のLFコード(line feed)の1byteを、fputc ('\n' ,fpr)などで出力すると、 0x0D 0x0Aの2byteが出力されます。(0x0DはCR: Carriage Returnです)

fgetc(fpr)などの入力は、0x0D 0x0Aの2byteを読み込むことでリターンし、 その時の戻り値が、'\n' つまり、0xA0の1byteになります。

つまり、改行に関連するコードだけ、メモリ1byteが2byteに変換して出力され、入力時は、0x0D 0x0Aの2byteが1byteの'\n'に変換されて入力されるわけです。
またテキストモードでは、テキストファイルの終端に使われるEOFのコード0x1Aを読み取ると、 ファイル終端と判断してfgetcの戻り値がEOF定義の-1になってしまいます。
よって、画像ファイルのようにバイナリファイルで、0x1Aを含むデータがあるファイルに対して、 前の実行例のように テキストモード("r")でfopenすると、 読み取りの中断が起きてしまいます。

fopen( ファイル名, オープンモード) におけるオープンモードの種類と意味
モードファイルがあるときの動作ファイルがないときの動作
"r"または"rb"読み出し専用ストリームポインタを返すエラーでNULLを返す
"w"または"wb"書き込み専用ストリームポインタを返す。 既存のファイルサイズを 0 にする新規に作成し、それへの書き込み専用ストリームポインタを返す。
"a"または"ab"追加書き込み専用ストリームポインタを返す。ファイル最後に追加します新規作成
"r+"または"rb+"読み込みと書き込みエラーでNULLを返す
"w+"または"wb+"書き込みと読み込み 既存のファイルサイズを 0 にする新規作成
"a+"または"ab+"読み込みと追加書き込み 最後に追加する新規作成