/*** FAR.c 大きなメモリの確保 ***/ /* 64KB = 65,536(0x10000) バイト以上のメモリを確保できます。 */ /* この例では、128KB (0x20000) のメモリを確保します。 */ /* 確保したメモリに、ファイルからデータを読み出します。 */ /* この例は読み出し専用なので、◆テストする時は、 */ /* あらかじめテキストファイルを作っておきます。 */ #include /* printf */ #include /* fopen */ #include /* fileno */ #include /* farmalloc */ #include /* getcwd */ #include /* strcpy */ #include /* far_memcpy */ #include /* jstrchr*/ #define unint unsigned int /* 型名の 別名を定義します。 */ #define unlong unsigned long /***** ◆メイン関数 ◆******************************************/ int main(int argc, char *argv[]) /* コマンドラインを使います。*/ { /***** ◆変数の宣言 *******************************************/ char f_buf[125]; /* ファイル名入力バッファ */ char fname[125], *cs; /* ファイル名バッファ( \/ 変換用) */ char cd_buf[125], *pcd; /* カレントディレクトリバッファ */ FILE *fp; /* ファイルポインタ */ int fd; /* ファイルハンドル格納用 */ unint size; /* ファイルサイズ格納用 */ char far *p, far *q; /* char 型の far ポインタ変数 */ /* q は使用しません。まとめて宣言する例です。 */ unlong m_size=0x20000; /* 確保するメモリのサイズ*/ char c; /* 読み出しバッファ */ unint i; /* ループ用の変数 */ char buf[256]; /* 作業用のバッファ */ /***** ◆ファイル名の入力 **************************************/ /* まず、ファイル名を f_buf[] に格納します。 */ pcd=getcwd(cd_buf, 120); /* カレントディレクトリ取得 */ if(argv[1]==NULL) /*** コマンドラインにファイルの指定がなければ入力します。***/ { printf("現在のディレクトリ = %s\n",pcd); printf("ファイル名 = "); gets(f_buf); /* f_buf[] に格納 */ } else /*** コマンドラインにファイルの指定があるなら、それを使います。*/ { strcpy(f_buf, argv[1]); } /* f_buf[] に格納 */ /***** ◆絶対パスの作成 ****************************************/ /* 上記で f_buf[] に入力されたファイル名は、 */ /* TEST.txt のような相対パスかも知れません。 */ /* C:\C86\TEST.txt のような、絶対パスのファイル名を作ります。 */ /* 作成した絶対パスは fname[] に格納します。 */ if( (f_buf[0]=='\\')||(f_buf[1]==':') ) /*** \C86 や D:\C86 のようなとき ***/ { if(f_buf[1]==':') /* ドライブの指定があるなら、 */ { strcpy(fname, f_buf); } /* そのまま使用。 */ else /* \C86 のような指定なら、 */ { strncpy(fname, pcd, 2); /* ドライブ名(C:)をコピー */ strcat(fname, f_buf); /* f_buf[] の内容を付け足します。*/ } } else /*** TEST.txt のようなとき ***/ /* getcwd() で得たカレントディレクトリ pcd[] に、付け足します。 */ { strcpy(fname, pcd ); /* fname[] ← カレントディレクトリ */ if( fname[3] == 0 ) /* C:\ のように3文字なら、 */ {} /* そのまま。 */ else /* C:\C86 のように続きがあるなら、 */ { strcat(fname, "\\"); } /* \ を付け足す。→ C:\C86\ */ strcat(fname, f_buf); /* 最後にファイル名を付け足します。 */ } /* → C:\C86\TEST.txt */ /** 絶対パスとファイル名が確定しました。***/ /***** ◆ファイル名の変換 ***************************************/ /* C言語では \ をエスケープコードを表わす記号に使用しています。*/ /* ディレクトリ記号には \ ではなく、/ を使う必要があります。 */ /* fname[] に含まれる \ を、すべて / に置換します。 */ /* 表示する時には \ の方が見易いので、*/ /* \ を使ったままのファイル名は、f_buf[] に保存しておきます。 */ strcpy(f_buf, fname); /* 変更前のファイル名を保存 */ cs=fname; /* cs に、fname[] のポインタを代入 */ for( i=0; i<125; i++ ) { cs=jstrchr(cs, '\\'); /* \ の位置を捜します。 */ if(cs == 0) { i=125; } /* 見つからなければ終了します。 */ else /* 見つかったら、 */ { *cs='/'; /* / を代入します。 */ cs++; /* 捜し始め位置を1進めます。 */ } } /** fname[] は、\ が / に変換されました。(f_buf はそのまま。) **/ /* C:/C86/TEST.txt のように変換されました。 */ /***** ◆ファイルをオープンします。*****************************/ fp=fopen(fname,"rb"); /* ファイルをオープンします。 */ if(fp==NULL) /* オープンできなかったときは、*/ { printf("\n%s\nファイルが見つかりません。\n\n",f_buf); return -1; /* ここでプログラムを終了します。*/ } /***** ◆ファイルサイズを読み出します。*************************/ fd=fileno(fp); /* ファイルハンドルを得ます。 */ size=(unint)filelength(fd); /* ファイルサイズを読み出します。 */ if(size==-1L) /* サイズの読み出しができなかった時は、*/ { printf("ファイルサイズ読み出し失敗\n\n"); return -1; /* ここでプログラムを終了します。 */ } /***** ◆メモリを確保します。***********************************/ p=farmalloc( m_size ); /* 大域メモリを確保する。(m_size=128KB)*/ if(p==NULL) /* メモリが確保できなかったときは、 */ { fprintf(stderr,"メモリ確保不可。---終了します。\n"); farfree(p); return -1; /* ここでプログラムを終了します。 */ } /***** ◆ファイルの内容を読み出します。*************************/ /* 読み出した内容は、確保したメモリに転送します。 */ /* これはハードディスクの処理なので、時間がかかります。 */ i=0; while( i<(unint)size ) /* ファイルの最後でなければ、 */ { fread(&c, 1, 1, fp); /* c に、1バイト読み出します。 */ *(p+i)=c; /* 確保してあるメモリにコピーします。 */ i++; /* 読み出しバイト数を+1します。 */ } /* データを処理する例 */ *( p ) ='Z'; /* 1バイト目に Z を代入します。 */ *( p+1 )='Z'; /* 2バイト目に Z を代入します。 */ /***** ◆確保したメモリから、バッファに転送します。*************/ /* メモリ内のデータの移動は高速に行われます。 */ /* p から buf に、256 バイトをコピーします。 */ far_memcpy( (char far *)buf, p, 32 ); /***** ◆読み出し結果を表示します。*****************************/ /* Cの関数には、far ポインタを処理できないものがあります。 */ /* prinrf() は far ポインタで文字列を表示できません。 */ /* far * 型で確保したメモリの内容は表示できないので、 */ /* buf[] にコピーした方を表示します。 */ /* %Fp は、farポインタを表示するための フォーマットコードです。*/ printf("確保メモリ先頭 p =%Fp\n", p ); printf("確保メモリ2番 p+1 =%Fp\n", (p+1) ); printf("確保メモリ末尾 p+m_size=%Fp\n\n",(p+m_size) ); printf("ファイル名=%s\n",f_buf); printf("ファイルサイズ=%u バイト\n",size); printf("読み出しサイズ=%u バイト\n",i); printf("--読み出し内容--\n"); printf("%s\n",buf); /* メモリから buf にコピーした内容。*/ /***** ◆終了 ***************************************************/ farfree(p); /* 確保したメモリを解放して、 */ if ( -1==fclose(fp) ) /* ファイルを閉じます。 */ { printf("ファイルのクローズに失敗しました。\n\n"); return -1; } printf("----------------------終了。\n"); return 0; /* 正常終了 */ } /*--end--*/