第 14 回 発展学習

本日の内容


このドキュメントは http://edu.net.c.dendai.ac.jp/ 上で公開されています。

14-1. 状態の記憶

ここでは変数に過去使用した値を保存することを考えます。 例えば文字列を一文字ずつ読んでいく場合、一つ前の文字を記憶しているとど うなるでしょうか? これは関数で言えば二つの点を得ることになり、差分や微分を計算すること、 つまり変化を知ることと同じことになります。 一つ前の文字と現在の文字を比較することで文字の変化を知ることができます。 例えば、空白の連続とか英字の連続を検出することができます。

なお、C 言語では「英字」「英数字」「空白、タブ、改行」などを調べる関数 isalpha, isalnum, isspace が#include <ctype.h> を指 定すると使えます。

例14-1

以下の例では、連続する空白を表示しません。 そのため、連続する空白を一つの空白にするプログラムになります。


#include <stdio.h>
main(){
  int c;
  char b;
  b='\0';
  while((c=getchar())!=EOF){
    if(!((c==' ')&&(b==' '))){
      printf("%c",c);
    }
    b=c;
  }
}

例14-2

以下は英数字の列を改行で区切って出力するプログラムです。


#include <stdio.h>
#include <ctype.h>
main(){
  int c;
  char b;
  b='\0';
  while((c=getchar())!=EOF){
    if((!isalnum(b))&&isalnum(c)){
      printf("\n");
    }
    if(isalnum(c)){
      printf("%c",c);
    }
    b=c;
  }
}

演習14-1

ファイルの単語を数えなさい。ただし、単語は isalpha が連続しているもの を指します。


演習14-2

下記の例のように連続した文字のある位置に ^ を表示しなさい。


This is a sweet apple.
             ^    ^

14-2. フラグ

ある処理を行なうかどうかを 1, 0 で表す変数をフラグと言いま す。 プログラムの途中でフラグを計算し、処理を行います。

例えば、各行を [] で括ることを考えます。入力が以下の通りだとします。


abc
def
ghi

この時、目標は以下を出力することです。


[abc]
[def]
[ghi]

ここでポイントは、行のはじまりで [ を出力し、改行の手前に ] を出力する ことです。 ] は改行を読んだ時出力すれば良いですが、[ はいつ出力すれば良いでしょう か? つまり行の始めはどうやって知れば良いでしょうか? 改行の直後の文字を読んだ時に出力すると考えれば前節の方法でも解決できま すが、ここでは特定の変数 flg が 1 の時に出力することを考えましょう。 そして flg をどうやって計算するか考えましょう。 これは、行のはじまりで 1 に、それ以外で 0 になってないといけません。 つまり、まずプログラムの開始時には 1 にしておきます。 そして、文字を読む毎の処理では、まず flg が 1 なら [ を出力します。 そして読んだ文字が改行文字なら ] を出力します。 改行文字だったら次の文字は行の始めになるので、 flg を 1 にしますが、それ 以外の文字だったら、次の文字は行の始めでないので flg は 0 にします。 そして、読み込んだ文字を(改行を含めて)表示します。

例14-3


#include <stdio.h>
main(){
  int c;
  int flg=1;
  while((c=getchar())!=EOF){
    if(flg){
      printf("[");
    }
    if(c=='\n'){
      printf("]");
      flg=1;
    }else{
      flg=0;
    }
    printf("%c",c);
  }
}

演習14-3

C 言語のプログラムで # で始まる行を表示するプログラムを書きなさい。


演習14-4

標準入力から文字を読み込み、 "" で括られた文字列だけを表示するプログラ ムを書きなさい。 但し、各文字列は一行ずつ行を変えて表示しなさい。

注意

作成したプログラムには " が単独で現れるので、そのプログラムをプログラ ム自身で処理すると誤動作します。 誤動作させないようにするのは難しいので、ここでは考えなくて良いです。


演習14-5

C のプログラム内のコメントをすべて消すプログラムを書きなさい。 但し、 C のコメントとは /* で始まって、 */ で終るもので、入れ子はでき ません。


演習14-6

C のプログラム内のコメントを抜き出して、存在する行番号とともにコメント の内容(/*, */ を除く)を表示しなさい。


坂本直志 <sakamoto@c.dendai.ac.jp>
東京電機大学工学部情報通信工学科