lC言語 組込み関数(2) '97. 1.10  
l.お知らせ 内容 LINK FILE   HTML Win PC Unix MS-DOS C C++ Mfc Java 
.C言語_ 3 フォ-マットコ-ド 6 演算子 9 FOR  集合デ-タ  目的別
1 表示してみる 4 変数と定数 7 条件判断 10 WHIILE  ポインタ     
2 エスケ-プ コ-ド 5 デ-タ入力 8 分岐   未使用  関数   ★ 

ファイルのオープン  ファイルハンドル  ファイルサイズの取得   ファイルのクローズ  シーク  リードライト位置   ファイル読み出し  ファイル書込み
メモリ領域の確保  メモリの開放   メモリ領域の確保(クリア)  メモリ領域の変更  大きな領域   2分法検索  整列
時刻の取得  時刻の変換  時刻/文字列 変換

ファイルのオープン (include = stdlib.h)
指定されたファイルを、ハードデスクから メモリ上にコピーします。
次に、ファイルに対する処理を行うために必要なデータを作成し、そのデータへのポインタを返します。
実際の処理は、そのデータを使って行います。

ファイルはメモリに読み出してからでなければ処理できません。
処理したいファイルを指定して fopen を呼び出すと、メモリ上のどこにファイルを読み出すか、などが決定されます。
それらのデータは構造体 FILE に書かれ、そのポインタ(ファイルポインタ)が返されます。
普通は、そのポインタを受取るためのポインタ変数を宣言して、そこに代入して使います。

FILE のデータ(メンバ)を直接使用することもできますが、ファイルを読み出すなどの処理を行う場合には fread などの関数が用意されていますので、具体的な処理を行う fread などの関数にファイルポインタをそのまま、引数として渡して処理させます。

   メモ : FILE は、stdio.h で定義されている構造体の別名です。
stdio.h では構造体の構造を定義しているだけです。
指定されたファイルのための具体的なデータは、fopen によって作られます。

FILE * fopen(const char *file, const char *mode)
file には、ファイル名を代入した文字配列のポインタを(または文字列をそのまま)記入します。
mode には、読み出すのか書込むのかを指定する文字を代入した文字配列へのポインタ(または文字をそのまま)を記入します。
r : 読み出し。ファイルがなければ、エラーになります。
r+ : 読み書き。 〃
w : 書込み。古いファイルの内容は消され、新しく作られます。
w+ : 読み書き。 〃
a : 追加書込み。ファイルが無い場合は、新しく作られます。
  追加位置はファイルの最後です。
a+ :読み書き。その他は a と同じ。
バイナリファイルの場合は、rb, r+b のように、b を付けて書きます。
バイナリモードの場合には、テキストファイルの最後を表わす 0x1A などの、文字以外のデータも読み書きされます。

これによって、FILE という構造体に、読み出しまたは書込みに必要なデータが作られます。

返り値は、作成された構造体へのポインタ(ファイルポインタ)です。
読み出しモードでオープンしようとしたファイルが無かった場合など、オープンできない場合には NULL を返します。
  NULL : Cコンパイラで用意されている 0 の別名。
EOF : stdoi.h で定義されている -1 の別名。
0 や -1 では意味がわかりにくいので、NULL(Null:無 何もない)や、ROF(End of file:ファイルの終り)などを、0 や -1 の代わりに使えるようになっています。

char Name[20]="D:/ABC.txt"; /*ファイル名バッファ*/
char buf[265]; /* 入力バッファ */
FILE *P; /* ファイルポインタを代入するためのポインタ */
P=fopen(Name,"r"); /* 読み出しモードでオープン */

用例
テキストファイルをに文字列を書込んで、次に読み出して表示する例です。
D:\ABC.txt というファイルが作られます。
#include <stdio.h>
main()
{
char buf[128];                  /* バッファ  	*/
FILE *fp;                       /* ファイルポインタの宣言。*/
/****** ファイルに書込み ********/
fp=fopen("D:/ABC.txt","w+");    /* ファイルをオープン。*/
fprintf(fp,"ABC\nDEF\n");       /* ファイルに文字列を出力。*/
/****** ファイルから読み出し *******/
fseek(fp,0,SEEK_SET);           /* 読み出し=先頭。後記参照。*/
fgets(buf,100,fp);              /* 1行目を buf に読み出し。*/
printf("%s",buf);               /*     表示。*/
printf("%s",fgets(buf,100,fp)); /* 2行目を表示。*/
printf("%d \n",fp->bufsiz);     /* FILE のメンバの表示例。*/
fclose(fp);                     /* ファイルをクローズ。 */
}
  メモ : ディレクトリの区切りを表わす記号には、\ の代わりに / を使います。
\ は文字列のフォーマットコードに使用されるため、使えません。

バッファ(Buffer:緩衝装置) : 正式なデータではなく、一時的なデータを格納するための変数をいいます。
この場合はファイルの内容を、表示するために変数配列 buf に格納していますが、表示してしまえば必要がないデータです。
同様に、一時的なデータを保存するファイルは、一時ファイルまたはテンポラリファイルまたは作業ファイルなどと呼ばれます。
 

ファイルハンドルの取得 (include = stdio.h)
MS-DOS がメモリ上にコピーされているファイルを管理するために付けている、ファイルの番号を得ます。
ファイルの処理を MS-DOS に手伝ってもらう場合には、ファイルハンドルで指定する必要があります。

int fileno(FILE *fp)
ファイルポインタ fp で示されるファイルの、ファイルハンドルが返されます。

メモ : 関数 fopen でファイルをオープンしてあれば、構造体 FILE にはファイルハンドルが格納されているので、そこから直接得ることもできます。
次のように、FILE のメンバ fd(ファイルハンドル)を指定します。
例  fp->fd ただし、fp はファイルポインタとする。

ファイルサイズの取得 (include = stdio.h)
ファイルの大きさを調べます。
long filelength(int fd)
ファイルハンドル fd で示されるファイルの、バイト数 が返されます。

ファイルのクローズ (include = stdio.h)
指定されたファイルの、メモリ上のコピーを消去します。
そのファイルを処理するために作られていた構造体のデータも消去されます。
(メモリが広く使えるように、オープン前の状態に戻されます。)

int fclose(FILE *fp)
ファイルポインタ fp で示されるファイルをクローズします。
返り値は 0 です。クローズできなかった場合は -1 を返します。

シーク (include = stdio.h)
int fseek(FILE *fp, long offset, int ptrname);
ファイルポインタ fp で示されるファイルのリードライト位置を設定します。
ptrname で、設定の基準点を指定します。
offset で、基準点からの偏移(オフセット)をバイト数で指定します。
ptrname で指定する基準点には、次のものがあります。
 SEEK_SET : =0 ファイルの先頭。ふつう、最初この位置になっています。
 SEEK_CUR : =1 現在処理している位置。
 SEEK_END : =2 ファイルの最後。
これらは stdio.h で別名定義されているので、数字/文字 どちらでも指定できます。
なお、読み書き処理を行うと、シークポイントは次に読み書きすべき位置に変ります。
(5文字読み出すと、5文字分移動します。)
 英語 : Seek:捜す。Cursol:注目点を示す滑子 カーソル。

返り値は 0 。シークできなかった場合は 0 以外の値を返します。

リードライト位置 (include = stdio.h)
現在読み書きしている位置を記録して、後で再びその位置に戻るための関数です。
int fgetpos(FILE *fp, fpos_t *ptr)  fp の現在位置を、ptr に格納します。
int fsetpos(FILE *fp, const fpos_t *ptr)  fp の現在位置に、ptr を設定します。
fp はファイルポインタ、ptr は fpos_t 型データへのポインタです。
fpos_t は、stdio.h で定義されている long 型の別名です。

返り値は 0 で、正しく実行できなかった場合は 0 以外の値が返されます。

ファイル読み出し (include = stdio.h)
テキストファイルではない バイナリファイルも 読み出しができます。
int fread(void *ptr, size_t size, size_t nelem, FILE *fp)
ポインタ ptr で示される配列に、ファイルを読み出します。
size には、読み出しデータ単位(バイト数)を指定します。
nelem には、読み出しデータ個数を指定します。
fp には、ファイルポインタにより、読み出すファイルを指定します。
返り値は、実際に読み出したデータの個数です。

ファイル書込み (include = stdio.h)
テキスト以外の、バイナリデータも書込みができます。
int fwrite(const void *ptr, size_t size, size_t nelem, FILE *fp)
ポインタ ptr で示される配列のデータを、ファイルに書込みます。
size には、書込みデータ単位(バイト数)を指定します。
nelem には、書込みデータ個数を指定します。
fp には、ファイルポインタにより、書込むファイルを指定します。
返り値は、実際に書込んだデータの個数です。


メモリ領域の確保 (include = stdlib.h または malloc.h>)
使用するメモリを確保します。
変数を宣言すると、コンパイラが自動的に変数を格納するためのメモリ領域(場所 範囲)を確保してくれます。
それとは別に、大きなデータを扱う場合などに、自分で大きさを指定して領域を確保します。
確保された領域はクリアされていません。(古いデータが残っているかもしれません。)
void *malloc(size_t n) size_t は unsigned の別名。
確保したいバイト数 n を指定します。
size_t(unsigned)は2バイトのデータですから、指定できるのは 0〜65,535 バイトの範囲です。
返り値は、確保した領域の先頭アドレス(ポインタ)です。
確保できなかった場合には NULL(= 0 )が返されます。

例  doubul *P;
P = malloc(256*4);
 1024バイトが確保されます。

用例
1024バイトを確保して、65〜90(A〜Z)を書込みます。
#include <stdio.h> /* printf */
#include <stdlib.h> /* malloc free exit*/
void main()
{
int i;
size_t n=1024;/* 確保するサイズ */
char *s;
s = malloc(n*sizeof(char));
if(s == NULL)
 { fprintf(stderr,"メモリが確保できません。\n");
   exit(2); /* 確保できないので終了します。*/
 }
printf( "%uバイトのメモリが確保されました。\n",
        n*sizeof(char) );
printf("書込み/表示テスト。\n");
for(i=0;i<26;i++){*(s+i)=i+65;};*(s+i)='\0';
printf("%s \n",s);
free(s);
printf("メモリを開放しました。\n");
}

メモリの開放 (include = stdlib.h または search.h)
malloc によって確保したメモリ領域を OS(MS-DOS) に返えします。
void free(void *p)
p で、確保してあるメモリ領域の先頭アドレス(malloc の返り値と同じ値)を指定します。
この操作を行わないと、プログラムが終了しても OS は まだ使われていると判断します。(Windows の場合。)
そして次にプログラムを起動すると、また別なメモリ領域を確保します。

メモリ領域の確保(クリア) (include = stdlib.h または search.h)
格納するデータの個数とサイズを指定して、メモリ領域を確保します。
確保された領域はクリアされます。 (すべて NULL が書込まれます。)
void *calloc(unsigned int nelem, size_t elsize)
格納するデータの個数 nelem とサイズ elsize を指定して、メモリ領域を確保します。

例  doubul *P;
P = calloc(256,4);
 1024バイトが確保されます。

メモリ領域の変更 (include = stdlib.h または search.h)
malloc または calloc によって確保したメモリ領域領域の大きさを変更します。
void *realloc(void *ptr, size_t size)
確保済領域の先頭アドレス ptr と、新たに確保する領域サイズ size を指定します。
ptr に NULL( =0)を指定すると、malloc と同じ動作をします。
size に NULL( =0)を指定すると、free と同じ動作をします。

例  doubul *P;
P = malloc(256*4);
P = realloc(P,2048);
 
 1024バイトが確保されます。
 2048バイトに変更されます。
都合により先頭アドレスが変更されるときにも、古い領域の内容は新しい領域にコピーされるので、書込み済のデータはそのまま保存されます。

大きな領域 (include = dos.h)
確保できるメモリ領域の大きさを調べます。
unsigned long farcoreleft(void)
以下はサイズが異なるだけで、前記と同様です。
void far *farmalloc(unsigned long size) 領域確保(非クリア)
void far *farcalloc(unsigned long nelem, unsigned long size) 領域確保(クリア)
void far *farrealloc(void far *fp, unsigned long size) 領域変更
void farfree(void far *fp); 領域開放
 far(遠くに 遥か) : メモリの広い範囲を操作するから。


2分法検索 (include = stdlib.h または search.h)
昇順に整列されているデータに対して、2分法検索を行います。
void *bsearch(const void *key, const void *base, size_t nmemb,
  size_t size, int (*compar)(const void *x, const void *y))
void *bsearch(検索データ,被検索データ,個数,データサイズ,比較関数);
key でポイントされるデータを、base でポイントされるデータ群の中から検索します。
nmemb と size で、被検索データの個数とデータのバイト数を指定します。
compar には、比較を行うための関数をポインタで指定します。
この関数には、strcmp(etc のページ参照)と同じ返り値のものを使用します。

返り値は見つかったデータへのポインタです。
見つからなかったときには NULL(空の文字列)へのポインタを返します。

用例
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
void main()
{
char S[5][3]={"AA","BB","CC","DD","EE"}; /* 被検索データ。*/
char s[3]="BB"; /* 検索するデータ。*/
char *p; /* 検索結果を格納するためのポインタ。*/
int (*CMP)()=strcmp; /* 比較関数のポインタを定義します。*/
p=bsearch(s,S,5,3,CMP); /* 2分法検索を行います。*/
if(*p != NULL)
{printf("%s \n",p);} /* 検索結果の表示。*/
else
{printf("見つかりません。\n");}
}

データの整列  (Include = stdlib.h または search.h)
void qsort(void *base, size_t nel, size_t width,
  int(*compar)(const void *x, const void *y))
void qsort(被整列データ,個数,データサイズ,比較関数);
base でポイントされるデータ群を昇順に並べ替えます。
nel と width で、データ群のデータ個数とデータのバイト数を指定します。
compar には、比較を行うための関数をポインタで指定します。


時刻の取得 (include = time.h)
コンピュータのタイマから時刻を取り出します。
1970年 1月 1日 0時 0分 0秒 からの秒数が得られます。
clock_t clock(void)
time_t time(time_t *t)
返り値の型 clock_t と time_t は、time.h で定義されている long 型の別名です。
time は、返り値と同じデータを、t でポイントされる変数にも代入します。
例  clock_t C; /* long C; でも可。*/
time_t T,U; /* long T,U; でも可。*/
C=clock();
T=time(&U); /* U にも代入されます。*/

時刻の変換 (include = time.h)
clock または time で得られた時刻データを、変換します。
struct tm *localtime(const time_t *t)  日本時間
struct tm *gmtime(const time_t *t)  世界標準時
t でポイントされる時刻データを、年月日 時 分 秒 などを表わす int 型のデータに変換します。
変換されたデータは、time.h で定義されている構造体に格納されます。

time.h では、データの構造を宣言しているだけで、データ名とその内容は localtime が作ります。
time.h は、作成したデータのポインタを返すので、これを受取るために、あらかじめポインタ変数を宣言しておきます。
例  struct tm *tp; /* ポインタ変数の宣言。*/
tp=localtime(&T); /* T は、元になる時刻データへのポインタ。*/
localtime が作成する構造体のメンバは、以下の用例を参照して下さい。

用例
#include <stdio.h>
#include <time.h>
void main()
{
clock_t T;     /* 時刻(秒)を受取るための変数 */
struct tm *tp; /* 変換データのポインタを受取るためのポインタ変数 */

T=clock();        /* 時刻(秒)を得ます */
tp = localtime(&T);   /* 変換/ポインタを得ます */
printf("%d 年 \n",(tp->tm_year)+1900 );
printf("%    4d 月 \n",(tp->tm_mon)+1 );
printf("%    4d 周 \n",tp->tm_wday );
printf("%    4d 日 \n",tp->tm_mday );
printf("%    4d 時 \n",tp->tm_hour );
printf("%    4d 分 \n",tp->tm_min );
printf("%    4d 秒 \n",tp->tm_sec );
printf("%    4d 日目 \n",(tp->tm_yday)+1 );
}
tm_year は、1900 年からの経過年数に変換されます。( 1970 ではなく )
tm_mon は、1月からの経過月数です。
tm_yday は、元日からの経過日数です。
なお、%  4d は、表示をそろえるためで、%d の応用です。

時刻/文字列 変換 (include = time.h)
char *ctime(const time_t *t)  例  P=ctime(&T);
clock または time で得られた時刻データを、文字に変換します。
ctime は作成した文字列へのポインタを返すので、これを受取るためのポインタ変数をあらかじめ用意しておきます。
 例 chsr *P;

char *asctime(const struct tm *tm)
localtime または gmtime で変換済みの時刻データを、文字に変換します。
ポインタ変数を用意しておくのは ctime と同じです。

これらは、次のような文字列を作成します。
Fri Jan 17 06:11:28 1997

用例
#include <stdio.h>
#include <time.h>
void main()
{
clock_t T; /* 時刻(秒)を受取るための変数。*/
char *P; /* 変換データを受取るためのポインタ。*/
T=clock(); /* 時刻(秒)を得ます。*/
printf( "%s",ctime(&T) ); /* 変換してそのまま表示。*/
P=asctime(localtime(&T)); /* 変換データのポインタを得ます。*/
printf( "%s",P); /* ポインタを使って表示。*/
}
ctime の用例では、返り値をそのまま printf に渡しているので、ポインタ変数を使用していません。
同様に、asctime は localtime の返り値を直接受取っています。


T

C言語  関数  組込み1  
 
  mtoga@sannet.ne.jp   登録日 '96. 6.15
URL : http://www.page.sannet.ne.jp/mtoga/index.html