第7章 関数の活用

 これまでの章で、C言語の基本的な文法の学習は済みました。これからは、今までの知識を元に、色々な関数を使って、色々な処理に挑戦していきます。この章は、Q&A形式で進めていきます。

1.ファイルへの出力処理

Q.キーボードから氏名、住所、電話番号の入力されたデータを、ファイルに保存するプログラムを作りたいのですが。

  まずは、プログラム例を示します。

 [ DATAOUT.C ]

#include <stdio.h>

void main(void)
{
  char name[25],addr[100],tel[15];
  FILE *fp;

  printf("氏名:");
  scanf("%s",name);
  printf("住所:");
  scanf("%s",addr);
  printf("電話:");
  scanf("%s",tel);
  fp=fopen("JUSHO.DAT","w");
  fprintf(fp,"%s,%s,%s\n",name,addr,tel);
  fclose(fp);
}

ファイルポインタという変数(fp)を定義



※scanfの入力は、半角スペース
 を使えないので注意!


 ファイル処理の一連の流れは、まず fopen( ) でファイルをこれから利用しようとするファイル名(上の例では"JUSHO.DAT")で開き(使える状態にすることを開くという)、開いたファイルを対象として読み書きの処理を行い、最後に fclose( ) でファイルを閉じるという方法を取ります。

 ファイルを開くときには、そのファイルをこれからどのように使うかを指定する必要があるのですが、今回はファイルにデータを書き込みたいということだったので、"w" と指定し、書き込み用にオープンしました。

 ファイルに書き込む関数は、たくさんの種類があるのですが、ここではもっともオーソドックスな fprintf( ) 関数を用いています。この関数は、これまで画面に表示するのに幾度となく使ってきた printf( ) 関数とほとんど同じ方法で使うことができます。


2.ファイルからの入力処理

Q.前のプログラムで作った、データファイルを読みとり、内容を画面に表示させたいのですが。

 今回は読み込みと言うことですので、fopen( ) は "r" で使います。

 プログラム例:[ DATAIN.C ]
#include <stdio.h>
#include <string.h>

void main(void)
{
  char name[25],addr[100],tel[15];
  FILE *fp;
  char buff[200];

  fp=fopen("JUSHO.DAT","r");
  fgets(buff,200,fp);
  fclose(fp);

  strcpy(name,strtok(buff,","));
  strcpy(addr,strtok(NULL,","));
  strcpy(tel,strtok(NULL,"\n"));

  printf("氏名:%s\n",name);
  printf("住所:%s\n",addr);
  printf("電話:%s\n",tel);
}

 データを読み込む関数には、fgets( ) というのを使いました。この関数は、ファイルから1行読みとってくる関数です。先ほどのファイルへ書き込んだ処理を思い出してみてください。「氏名,住所,電話\n」という形式でした。カンマ( , )で区切って1行に3つのデータが書き込まれたわけです。これを fgets( ) で buff という変数に格納し、その後 strtok( ) 関数を使って、それぞれの変数に分解しています。

<練習> 6章の最後に作った英単語学習プログラムを、ファイルから英単語データを読み出して出題する形式に作りかえなさい。



3.テキスト画面の制御

Q.画面の好きな位置に好きな色で文字を表示したいのですが。

 これまで作成したプログラムは、どれも真っ黒の画面に白い文字が表示されるだけの素っ気ないものばかりでした。ですから、このように思われた方も多いのではないでしょうか。しかし、Cには残念ながら、このような処理を行う関数は持ち合わせていません。Cは元々UNIXなどのOSを記述する目的で開発され、移植性の良さが特徴です。どのマシーンでも、同じプログラム命令で動くようにということで、機種に依存する部分は標準化されていないのです。だからといって、できないわけではありません。Cは何でもできるプログラミング言語なのです。

 この処理を実現する方法はいくつかありますが、もっとも簡単な方法をここでは紹介しましょう。MS−DOSにはエスケープシーケンスという画面制御の方法があります。これを利用すれば良いのです。

 他にもたくさんあります。詳しくは、MS−DOSのマニュアルなどに載っていますので、参照してください。

 プログラム例:[ SCRNTEST.C ]
#include <stdio.h>

/* #define 文で式の簡略化を図る */
#define cls    printf("\x1b[2J")
#define curs_on  printf("\x1b[>5l")
#define curs_off  printf("\x1b[>5h")
#define locate(x,y) printf("\x1b[%d;%dH",y,x)
#define color(c)  printf("\x1b[%dm",c)

void main(void)
{
  cls;
  curs_off;

  /* 文字の位置・色を設定してからprintf()で書く */
  locate(20,5);
  color(46);
  printf("こんにちは!!");

  getch();  /* キー入力を待つ */

  /* 終了前に設定を元に戻す */
  color(37);
  curs_on;
  cls;
}

※プログラムの説明


<練習> これまでに作成したきた英単語練習プログラムを、文字の表示位置や色などをうまく使って、見栄えのするプログラムに変えなさい。

4.グラフィック処理
Q.画面に□や△や○などの図形を描きたいのですが。

 これもやはり機種に依存する機能ですので、標準では扱うことができないものです。しかし、何でもできるC言語ですから、実現は可能なのですが、今度は先ほどのテキスト画面制御ほど簡単にはできません。使用しているパソコンが、どうやって画面にグラフィックを描くのか、といった原理を知らないといけないのです。そうなると、誰でも簡単に取り組めるというものではなくなってしまうので、ここでは説明を避けます。かといって、あきらめたのではこの先進歩できなくなってしまいますので、ここではもっと良い方法をお教えします。

 C言語は関数さえあれば、後は誰でも簡単にすごいプログラムが書ける言語なんです。このグラフィックの処理も関数さえあれば、原理なんて何も知らなくも簡単に実現できます。ただ、残念なことに標準では備わっていなかっただけの話しなのです。こういう誰でも使いたいような重要な関数は、誰かしらがもうすでに作っています。それを使わせてもらいましょう。

 今回は、「調味料セット」という、パソコン通信で配布されているLSI−Cの機能を補う関数集(これをライブラリという)を使ってみます。関数の使い方に関しては、FLAVOR98.MAN に詳しく書いてありますので、まずはどんな関数があるのか一通り目を通しておきましょう。

 さて、問題の□や△や○の描き方ですが、次の名前の関数を使います。

 これらの関数を使うには、必ず ginit( ) , gscreen( ) を使い、グラフィック関係の初期化をしておかなくてはいけません。また、プログラムの最後には、グラフィック処理を終わりにするということで、gterm( ) 関数で終了処理をしなければなりませんので、注意して使いましょう。

 次に、「調味料セット」の関数を使った例を示します。前ページでエスケープシーケンスを使って処理していた内容も、このライブラリに関数が設けられていますので、そちらを使うことにします。

 プログラム例:[ GRAPTEST.C ]
#include <stdio.h>
#include "screen.h"
#include "graph98.h"

void main(void)
{
  int i;

  /* テキスト画面の初期化 */
  cursor(0);
  tfnkey(0);
  CLS();

  /* グラフィック画面の初期化 */
  ginit();
  gscreen(3,1,0,1);
  gcls();
  gboxf1(0,0,639,399,5,1);
  gbox(75,45,565,100,3);
  gsymbol4("これから英単語の学習を始めます",80,50,0,2,5,2,3);

  getch();   /* 入力待ち */

  for(i=0;i<7;i++) gcircle1(130+i*50,300,80,80,i+1);

  getch();

  /* 終了処理 */
  gcls();
  gterm();
  tfnkey(1);
  cursor(1);
  CLS();
}

<練習> 英単語学習のプログラムを、「調味料セット」を使って完成させなさい。