ログイン
kid's world

ライブラリ関数

標準入出力に関する関数

ここからは,主にライブラリ関数の説明をする。関数の引数の型名や戻り値の型を明確にするために,プロトタイプ宣言の形にのっとってそれぞれの関数を紹介することとする。

標準入力・標準出力・標準エラー出力

ファイルを扱うときには最初にfopen関数を使ってファイルポインタを得るが,あらかじめ使えるようになっているファイルポインタとして,stdout,stdin,stderrがあり,それぞれ標準入力,標準出力,標準エラー出力と呼ばれている。

基本的には,これらはファイルと結び付けられているのではなく,標準入力はキーボード,標準出力と標準エラー出力は画面につながっている。ここで紹介するprintf関数やscanf関数などは,stdoutやstdinを介して画面やキーボードにアクセスしている。

printf関数

printf関数は指定した文字列を標準出力に出力し,書き出された文字数をint型で返す。

int printf(char *文字列, ...);

「文字列」引数には出力する文字列を指定する。なお,この文字列の中に「%」とそれに続く変換文字を含めると,「第2引数以降に指定した値を文字列に変換したもの」によってその部分が置き換えられる。変換文字の主なものをTable 8に示す。

Table 8: printf関数の変換文字

変換文字引数の型意味
cchar文字を表示する
hdshort整数値を表示する
dint整数値を表示する
ldlong整数値を表示する
fdouble実数値を表示する
Lflong double実数値を表示する
schar *文字列を表示する
pvoid *ポインタとして表示する

たとえばint型変数iとjの内容を表示したい場合は,

printf(変数i=%d, 変数j=%d", i,j);

とする。すると変数iとjの内容が文字列に変換され,その文字列がそれぞれの「%d」と置き換えられて表示される。たとえばそれぞれの変数に10と20が入っていたとすると,

変数i=10, 変数j=20

と表示される。

scanf関数

scanf関数は標準入力からの文字列を変換文字に従って変換し,それを第2引数以降に指定されたポインタの指し示す先に書き込む。そして,変換された項目数をint型で返す。

int scanf(char *文字列, ...);

printf関数と同じように,「文字列」引数には「%」と変換文字の組を指定するが,printf関数の変換文字とは少々異なることに注意したい。変換文字の例をTable 9に示す。

Table 9: scanf関数の変換文字

変換文字データ
d10進数int型
hd10進数short型
ld10進数long型
x16進数int型
hx16進数short型
lx16進数long型
f実数float型
lf実数double型
Lf実数long double型
c文字char型
s文字列char*型

たとえば数値の入力を受け付けてそれをint型変数iに代入したいときは,

scanf("%d",&i);

とする。第2引数以降に与えるのはポインタなので,アドレス演算子を使っていることに注意しよう。

scanf関数は,1文字得るための「%c」を除いて,データを空白文字で区切って処理する。たとえば文字列として「%d%d」が指定してあったとき,「10」「20」と1行ずつ入力しても,「10 20」とスペースで間を空けて指定しても同じことになる。

文字列「%s」を使って入力したいときは,char型へのポインタを指定する。ただし,その先に十分なメモリが確保されていることが条件である。また,空白文字が入力されると,そこで区切られてしまうことに注意したい。

getchar関数

scanf関数で変換文字に「%c」を指定すると標準入力から空白文字も含めて1文字ずつ得ることができるが,getchar関数を使っても同じことができる。getchar関数は,標準入力から得た文字を返す関数である。

int getchar(void);

文字列

C言語では,文字列はchar型へのポインタか,char型の配列で表現する。すなわち,メモリ上に連続的に文字を並べて表現する。文字列の終わりは必ずヌル文字,すなわち’\0’で終わる。以下で紹介する2つの関数を含む,文字列を扱うライブラリ関数のほとんどはstring.hで宣言されているので,インクルードすることを忘れないようにしよう。

文字列の代入

文字列型という型はないため,代入演算子で文字列を代入することはできない。文字列の先頭からヌル文字までのメモリ内容をすべてコピーする必要がある。これは次に示すstrcpy関数で行うことができる。

char *strcpy(char *コピー先, char *コピー元);

この関数を実行すると,「コピー先」引数に指定したポインタの指し示す先に,「コピー元」引数に指定したポインタの指し示す先からヌル文字までの内容をコピーする。「コピー先」に指定したポインタの指し示す先に,十分なメモリが確保されていることが必要である。

文字列の連結

文字列の連結は,strcat関数で行うことができる。

char *strcat(char *連結先, char *連結元);

この関数を実行すると,「連結先」引数に指定したポインタの指し示す先に存在する文字列の末尾に,「連結元」引数に指定したポインタの指し示す先にある文字列を追加する。strcpy関数と同様に,受け側に十分なメモリが確保されていなければならない。

ファイル

ファイルは,バイト単位のデータの連なりである。変数や配列などのデータはすべてバイト単位でメモリ上で表現されているため,それをそのままファイルに書き込んで長期間保存することができる。このようにして作られたファイルをバイナリファイルと呼ぶ。それに対して文字データで構成されるファイルを,テキストファイルと呼ぶ。

ファイルポインタの取得と解放

ファイルは,読み込みも書き込みも,fopen関数を使って目的のファイルへのファイルポインタを得ることから始まる。ファイルに対するアクセスは,ファイルポインタを通して行われる。ファイルポインタは「FILE *」型であり,stdio.hで定義されている。ファイルに対するアクセスが終了したら,必ずfclose関数の引数にファイルポインタを渡して,ファイルを閉じる。

この2つの関数の書式は以下のとおりである。

FILE *fopen(char *ファイル名, const char *モード);
int fclose(FILE *ファイルポインタ);

fopen関数の「モード」引数には,Table 10に示す文字列が指定できる。通常はテキストファイルとして開かれるが,「モード」引数に指定する文字列に「b」を付け加えるとバイナリファイルとして開かれる。

Table 10: fopen関数の「モード」引数

モード意味
"r"読み出し用にファイルを開く。ファイルが存在しない場合や見つからない場合は失敗する。
"w"書き込み用にファイルを作成、ファイルが存在する場合はそのファイルの内容は破棄する。
"a"追加書き込みのために既存のファイルを開く。ファイルが存在しない場合は作成する。
"r+"読み書き用に開く。ファイルは存在していなければならない。
"w+"読み書き用にファイルを作成。ファイルが存在する場合はそのファイルの内容は破棄する。
"a+"読み出しと追加の両方のモードでファイルを開く。ファイルが存在しない場合は作成する。

たとえば「"wb"」を指定すると,バイナリファイルを書き込み用に作成する。

何らかのエラーによってファイルが開けなかったとき,fopen関数はNULLを返す。もし「ファイルが開けなかったときにプログラムを終了したい」場合は,List 1のように書くとよいだろう。

List 1: ファイルが開けなかった時の処理例

#include <stdio.h>

main()
{
  FILE *fp;

  if((fp=fopen("file.txt","w")) == NULL) {
    printf("ファイルが開けませんでした。\n");
    return;
  }
  
  (ファイルへの書き込み処理をここで行う)
  
  fclose(fp);
}

テキストファイルの扱い方

fopen関数でテキストファイルとして開いたあと,実際に読み書きをするにはfscanf関数とfprintf関数を使う。それぞれscanf関数,printf関数と使い方は同じであり,異なるのは引数の先頭にファイルポインタが追加されていることである。逆にいうと,scanf関数とprintf関数は,それぞれ先頭にstdinとstdoutを付け加えたfscanf関数とfprintf関数と同じである。

scanf(...) → fscanf(stdin, ...)
printf(...)→ fprintf(stdout, ...)

また,1文字ずつ文字を取り出したいときは,fgetc関数を使う。

int fgetc(FILE *ファイルポインタ);

「fgetc(stdin)」とすれば,それはほぼ「getchar()」と同じ意味である。fgetc関数とfscanf関数は,ファイルの終端まで読み込むとEOFを返す。

バイナリファイルの扱い方

fopen関数でバイナリファイルとして開いたあとは,fread関数とfwrite関数を使って読み書きができる。ファイルの終端まで読み込んだとき,feof関数が0以外の値となる。それぞれの関数の書式は次のとおりである。

size_t fread(void *バッファ, size_t サイズ, size_t 個数, FILE *ファイルポインタ);
size_t fwrite(void *バッファ, size_t サイズ, size_t 個数, FILE *ファイルポインタ);
int feof(FILE *ファイルポインタ);

fread関数とfwrite関数の引数は同じで,第1引数にポインタを指定する。fread関数ならばこのポインタの指し示す先にデータが読み込まれ,fwrite関数ならば書き込む内容をここに用意しておく。「サイズ」で指定したサイズのデータが「個数」で指定した個数ぶんだけ読み書きされる。一般的には「サイズ」には読み書きするデータの型のサイズを指定し,「個数」には一度に読み取るデータの個数を指定する。第4引数にはファイルポインタを指定する。

メモリの確保と解放

メモリの確保や解放は変数を宣言すれば自動的に行われるが,それを自分で行うことによって柔軟にデータを取り扱うことができるようになる。以下で説明する関数は,stdlib.hで宣言されている。これらの関数を利用するときは,stdlib.hをインクルードしよう。

malloc関数

メモリを確保するにはmalloc関数を使う。

void *malloc(size_t サイズ);

引数には確保したいメモリのバイト数を指定する。戻り値は確保した領域の先頭を指すポインタである。したがって,sizeof演算子を使って,

int *p;
p=malloc(sizeof(int));

と書けば,int型変数1つぶんの領域が確保できる。

free関数

確保したメモリは,不要になったら必ずfree関数の引数にポインタを指定して解放する。

void free(void *ポインタ)

たとえば,malloc関数で確保したメモリの先頭を,ポインタ変数pが指し示している場合は,

free(p);

とすることで解放することができる。


バグとアルゴリズム」へ進む

広告


©Toshio Koide 1996-2007.

目次

リンクについて

リンクは御自由にどうぞ。

メール

mail.gif

広告