入力(2)

本日の内容

    11-1. 前回の復習
    11-2. ファイル処理の演習
    11-3. scanf
    11-4. 引数
    11-5. 授業のまとめ
    11-6. 余計なお世話

11-1. 前回の復習

標準入力、出力

#include <stdio.h>
main()
{
  char c;
  while((c=getchar())!=EOF)
  {
    putchar(c);
  }
}

getchar(),putchar(c)の働き

getchar() は一文字読み、 putchar(c) は一文字書く。 では、いったいどこから読み、どこに書くのか?

簡単な覚え方
getchar() はキーボードから一文字読む。 putchar(c) は画面に文字 c を書く。
正式な覚え方
getchar() は標準入力から一文字読む。 putchar(c) は標準出力に一文字書く。

a.exe を動かした時、標準入力、標準出力に何も指定しないと、それぞれキーボード、画面になる。

標準入力にファイルを指定するには……

a.exe < ファイル

この指定をして、 getchar() をすると、ファイルから文字を一文字ずつ読み込む。

標準出力にファイルを指定するには……

a.exe > ファイル

この指定をすると、 putchar(c) でファイルに一文字ずつ書いていく。

さらに簡単な例

#include <stdio.h>
main(){
  putchar('a');
  putchar('b');
  putchar('c');
  putchar('\n');
}
#include <stdio.h>
main(){
  int i;  
  for(i=0;i<10;i++){
    putchar('a');
  }
  putchar('\n');
}

数字の文字列の表現から数値への変換方法

ステップ1
2 進数とはなにか……

1011(2)=1*2^3+0*2^2+1*2^1+1*2^0
         (x^y は x の y 乗を表す)

数字の表現から数値へはこのような計算をすれば良い。

ステップ2
プログラムで処理するにはどうするか……

漸化式的発想を使う

101
1010
10100

は101*1, 101*2, 101*2^2 となる。
(十進数だと *1, *10, *10^2 になる)

1011 という数の表現を計算することを考える。 左から文字を読んでいって、既に 101 までが

1*2^2+0*2^1+1*2^0=5(10)
と計算が終っているとする。 すると
1011=1010+1=101*2+1
より、 既に解釈が終っている数を 2 倍してから、注目している桁の表す数を足せば良い。

つまり、

とする。今注目している桁までの値は次のように計算できる。

x=x*2+y

この式で、今注目している桁までの値が求められる。 これを各桁に対して繰り返すと、二進数の値を求めることができる。


11-2. ファイル処理の演習

注意点

Windows の MS-DOS プロンプトにはバグがあるらしい。 EOFを読み込んだ直後に画面に文字を出す場合、その前に

printf("\n");

と改行を一行出力しないと、文字が出ない。

演習11-1

  1. ファイルの文字数を数えるプログラムを書け
  2. 作ったプログラムの文字数を数えさせよ

演習11-2

  1. ファイルの中に「a」という文字がいくつあるか数えるプログラムを書け
  2. 作ったプログラムに「a」が何文字あるか数えさせよ

演習11-3

  1. ファイルの中の「a」という文字を大文字(つまり「A」)に変えて表示するプログラムを書け
  2. 作ったプログラム中の「a」を大文字に変えて表示せよ

演習11-4

  1. ファイルの行数を数えるプログラムを書け (ヒント: 行は '\n' で終る)
  2. 作ったプログラムの行数を数えさせよ

演習11-5

  1. ファイルを一行ずつ空けて表示するプログラムを書け
  2. 作ったプログラムを一行ずつ空けて表示させよ

演習11-6

  1. 3 行目だけを表示するプログラムを書け
  2. 作ったプログラムの 3 行目を表示せよ (注意: ファイルが 2 行以下だったら、何もせずに終了しなくてはいけない。)

演習11-7

  1. 「a」を含む行だけを表示するプログラムを書け
  2. 作ったプログラムで、「a」を含む行だけを表示せよ

演習11-8

  1. 各行の先頭 3 文字だけを表示するプログラムを作りなさい。
  2. 作成したプログラムの各行を 3 文字だけ表示しなさい。 (注意: ある行に 2 文字しかなければ、 2 文字だけを表示する)

演習11-9

  1. 各行の先頭の空白の数を出力するプログラムを書きなさい。
  2. 作成したプログラムの各行の先頭の空白の数を出力しなさい。

演習11-10

MS-DOS コマンドの edit は次のようなクセがある。 カーソルは enter を押しても行の先頭に戻らず、前の行の先頭の空白の数と同じ数だけ空白が挿入される。 従って、WWW からカットバッファを利用して edit に貼り付けを行うと、プログラムには余分な空白が挿入されてしまう。

そこで、挿入された余分な空白を取るプログラムを作りたい。 次の流れに従ったプログラムを作りなさい。

  1. 取り除く空白の数 = 0;
  2. ファイルが終るまで以下を繰り返す
    1. 行を読み込む
    2. 空白を取り除いて行を表示する
    3. 取り除く空白の数 = 読み込んだ行にある先頭の空白の数

11-3. scanf

C 言語では、printfと反対の、標準入力から数を読み込むscanf 関数がある。

#include <stdio.h>
main()
{
  int i;

  printf("input an integer ");
  scanf("%d",&i);
  i*=2;
  printf("\nTwice the input value equals %d.\n",i);
}
変数の前に「&」をつけることに注意

演習11-11

入力した数に 1 を足して表示するプログラムを書きなさい。

演習11-12

二つの数を入力し、合計を出力するプログラムを書きなさい。


11-4. 引数

a.exe 123という書式でプログラムに値 123 を渡す方法を解説する。

これは main 関数の引数として渡され、次のような書きかたになる。

#include <stdio.h>
main(int argc, char* argv[])
{
  int i;

  printf("%d\n",argc);
  for(i=0;i<argc;i++){
    printf("%d,%s\n",i,argv[i]);
  }
}

但し、 char* argv[]という書き方はこの授業の範囲を越えるので、 文法的な解説はしない。


11-5. 授業のまとめ

この授業で説明したこと。

法律・倫理

コンピュータの仕組

オペレーティングシステム Windows の基本的な仕組

表計算の仕方

プログラミング

この授業で教えなかった大きな話題

今後目指すべき目標

  1. コンピュータを使って、レポートを書けるようになる。 (数式の表示、グラフや表の貼り込み)
  2. コンピュータを使って計算が出来るようになる。 (実験データの整理)
  3. いろいろなプログラムを書けるようになる。
  4. プログラミング言語をいろいろ覚えてみる。
    GUI を使ったプログラムを作りたい。
    Tcl/Tk, Perl/Tk, C+Gtk(Windows, Macintosh, UNIX のどれでも同じプログラムが動く)
    オブジェクト指向型言語を学ぶ
    Java, Objective C(C++ は中途半端), Effel, Small Talk
    (C++ の作者へのインタビューという設定で作られたジョーク記事 Bjarne Stroustrup Interview about C++)
    データを扱う能力の高い言語を使いたい。
    Lisp
    変ったプログラミングを覚えたい
    論理型言語Prolog
  5. プログラミングの能力を高めたい

11-6. 余計なお世話

大人の学習法を身に付けよう!

大人の学習法とは……
自己責任と自立
授業とは……
授業は自分が学習する上での一つの教材に過ぎない。 基本的に学習は独学。自分で学びたいことを授業を利用して学ぶ。 自分の学習目的が達成できるように、自分で学習法を考える。

大学の勉強は受験勉強より難しいです。 また、各授業には目標があります。 目標に到達するため、授業中に難しい内容が出てくることはしばしばあります。 さらに、世の中のことがらは全て体験なしに説明が可能であるわけではありません。 「演習」や「実験」という授業では、実際に試すまで理解できないことがらが多く出てきます。 また、また世の中には理解することが難しいことがらが多くあります。 理解するのに何日もかかることというのもあります。 授業の内容は、誰もがなにもかもその場で全て理解できることであるという保証はありません。


坂本直志 sakamoto@c.dendai.ac.jp