ログイン
kid's world

ファイルを扱う具体例

具体例

ここで,ファイルの読み書きを行う具体例を示そう。

HTMLファイルのタグを取り除く

HTMLのタグは,「<」から始まり,「>」で終わるが,その部分だけを無視し,そのほかの部分を表示するプログラムはどのようにして作ることができるだろうか。

基本的な部分は,List 4のファイルの内容をそのまま表示するプログラムが流用できる。あとは「<」から「>」までを表示しないようにするための方法について考ればよい。

(注意:ファイルの中に「<」が現れてもタグの始まりとしてみなさない条件もあるが、ここでは簡単のためそれは考えない。)

まずputchar関数で文字を表示する前に,変数cの内容を確認する。このとき,「<」以外ならばそのまま表示するが,「<」だったときは「>」が現われるかファイルの終端までfgetc関数で1文字ずつ読み込んで破棄するようにする。

これは,

while(c!='>' && c!=EOF)
  c=fgetc(fp);

とすればできる。

したがって,プログラム全体としては,List 5のようになる。

List 5:タグを取り除くプログラム

#include <stdio.h>
#include <stdlib.h>

main()
{
  FILE *fp;
  int c;
  char filename[100];
  
  printf("ファイル名:");
  scanf("%s",filename);
  
  if ((fp=fopen(filename, "r")) == NULL) {
    perror("ファイルが開けません");
    exit(1);
  }
  
  while((c=fgetc(fp)) != EOF) {
    if (c=='<') {
      while (c!='>' && c!=EOF)
        c=fgetc(fp);
    }
    else
      putchar(c);
  }

  fclose(fp);
}

配列を保存する

配列の内容を保存する場合について,テキストファイルを使った場合と,バイナリファイルを使った場合について考えよう。ここでは,100個の要素を持つint型の配列の中身をファイルに保存する例を考える。

テキストファイルの場合は配列に入っている数字をfprintf関数でファイルに文字列として書き込んでいく。このとき,それぞれの数値の間に,空白文字を入れなければならないことに注意しよう。改行でもスペースでもかまわない。もし空白文字を入れないと,数字の羅列になってしまってどこが区切りかわからなくなってしまう。読み込みは,fscanf関数を使って行う。

List 6に例を示そう(注意:List 6はあくまでサンプルであり,エラーに対する処理を行っていないことに注意。配列の初期化/入力文字のチェックなどの追加をぜひ読者自身の力で行っていただきたい)。このプログラムでは,サイズ100のint型配列をファイルに読み書きを行っている。また,配列のそれぞれの要素を表示したり変えたりできるようになっている。注意するべきなのは,fprintf関数で「%d」のあとにスペースが入っていることだ。

List 6: 配列の保存(テキストファイル版)

#include <stdio.h>

main()
{
  int op,i,j;
  int a[100];
  FILE *fp;

  do {
    printf("1.ファイル読込 2.ファイル書込 3.内容表示・変更 4.終了:");
    scanf("%d",&op);
    
    switch (op) {
    case 1:
      fp=fopen("data.txt","r");
      for(i=0; i<100; i++)
        fscanf(fp, "%d", &a[i]);
      fclose(fp);
      printf("読み込みました。\n");
      break;
    case 2:
      fp=fopen("data.txt","w");
      for(i=0; i<100; i++)
        fprintf(fp, "%d ",a[i]);
      fclose(fp);
      printf("書き込みました。\n");
      break;
    case 3:
      printf("何番のデータですか(0〜99):");
      scanf("%d",&i);
      printf("a[%d] = %d\n", i, a[i]);
      printf("データを書き換えますか(1:Yes/2:No):");
      scanf("%d",&j);
      if(j==1){
        printf("a[%d] = ", i);
        scanf("%d",&j);
        a[i]=j;
      }
    }
  } while (1<=op && op<=3);
}

バイナリファイルを扱うプログラムは,List 6のfscanf関数とfprintf関数の部分をそれぞれfread関数とfwrite関数に置き換え,fopenのモードを「"rb"」と「"wb"」に変更するだけでできあがる。また,List 6のようにfor文を使って1つ1つデータを書き込んでもよいが,配列の中身はメモリ上に並んで記憶されているので,List 7のようにfwrite関数やfread関数を一度呼び出すだけでもよい。配列の先頭へのポインタは,配列名のみで表せることに注意しよう。List 6のcase 1とcase 2の部分をList 7で置き換えれば,バイナリファイル版のプログラムができあがる。

List 7: 配列の保存(バイナリファイル版)

    case 1:
      fp=fopen("data.bin","rb");
      fread(a, sizeof(int)*100, 1, fp);
      fclose(fp);
      printf("読み込みました。\n");
      break;
    case 2:
      fp=fopen("data.bin","wb");
      fwrite(a, sizeof(int)*100, 1, fp);
      fclose(fp);
      printf("書き込みました。\n");
      break;

なお,「sizeof(int)*100」の部分は,「sizeof a」とすることもできる。配列名を与えることによって,その配列の確保しているメモリのバイト数を得ることができる。


画面とキーボードへのファイルポインタ」へ進む

広告


©Toshio Koide 1996-2007.

目次

リンクについて

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

メール

mail.gif

広告