Standard Input/Output and Redirection
(標準入出力とリダイレクト)
Computing Practice I
4th lecture, April 28, 2016
http://www.sw.it.aoyama.ac.jp/2016/CP1/lecture4.html
Martin J. Dürst
Today's Schedule
- Minitest
- About last week's exercises
- Rolling pin programming
- The DRY principle
- String representation
- Functions for input and output
- Buffer overflow
- Standard input/output
- Why tests?
- About today's exercises
ミニテスト
- 授業開始までにログイン済み
- 授業開始まで教科書、資料、筆箱、財布などを鞄に入れ、鞄を椅子の下に
- テスト終了後その場で待つ
C 言語の最初の本
- The C Programming Language, Brian W. Kernighan and Dennis M.
Ritchie, 1978
- 略称: K&R
- コンパクトで概念中心の名作
- 組版に C 言語で書かれた Unix のツールを使用
"hello world"
の原点
- 多くの (自然) 言語に翻訳
- 今は早いが、夏休みに復習として読むとよい
前回の演習結果
|
03B1 |
03C1 |
03C2 |
03C3 |
03C4 |
100点 |
86 |
57 |
28 |
21 |
12 |
60点 |
2 |
31 |
58 |
59 |
62 |
部分点 |
- |
- |
- |
- |
4 |
エラー |
- |
- |
2 |
2 |
1 |
未提出 |
1 |
1 |
1 |
7 |
10 |
前回の演習について
- Program Checking System で入力がわからないとき、Q&A
フォーラムで質問
- Q&A フォーラムの命題の選び方
- 悪い例:
「課題の提出」、「チェッキングシステムのエラー」
- 良い例: 「03C3 の check number 15 の入力」
- 一問一答 (Q&A フォーラムは LINE などではない)
- 困ったときには距離をとるのが大事
Exercise 03C1
(Analysis of Student Numbers)
Length of Solutions
|
Lines |
Bytes |
Longest |
174 |
7574 |
Shortest |
45 |
1143 |
Rolling Pin Program
- A program that gets longer and longer due to copy/paste
- Similar to rolling out dough with a rolling pin
- Not (yet?) a widely known term
Problems:
- Difficult to get overview
- Difficult to check/verify
- Difficult to change
- Inefficient
- Bad feeling, (bad) code smell
DRY
The DRY Principle
- Don't Repeat Yourself
- 同じことを繰り返すな!
- よいプログラム・プログラマーの大原則
- 情報テクノロジーの大原則
- (数学的) 概念: 独立性 (independence)、直交性
(orthogonality)、直積 (Cartesian product)、抽象化 (abstraction)
- プログラム概念: 繰り返し (repetition)、関数 (function)
など
直積の具体例
|
数物理 |
化学 |
電気 |
機械 |
経シス |
情テク |
... |
19xx |
|
|
|
|
|
|
|
200x |
|
|
|
|
|
|
|
20xx |
|
|
|
|
|
|
|
- すべての組み合わせの合計は
27 個
- 学科と年度を独立すると
11 個 (200x と 20xx の区別は不要)
- 独立されたものが修正しやすい
Representation of Strings
- In C、a string is a byte array (array of
char
)
- The type
char
can be interpreted both as a character and as
a small number
- The end of a string is signaled by a
'\0'
(null
character)
- Example:
char str[] = "Aoyama\n";
|
str[0] |
str[1] |
str[2] |
str[3] |
str[4] |
str[5] |
str[6] |
str[7] |
Character |
'A' |
'o' |
'y' |
'a' |
'm' |
'a' |
'\n' |
'\0' |
Number (decimal) |
65 |
111 |
121 |
97 |
109 |
97 |
10 |
0 |
Number (hexadecimal) |
0x41 |
0x6F |
0x79 |
0x61 |
0x6D |
0x61 |
0x0A |
0x00 |
Representation of Line Breaks
- Windows, Internet (e.g. SMTP, HTTP):
Carriage Return, Line Feed (CRLF, 0x0D 0x0A)
- Unix/Linux/cygwin, Mac (OS 10), inside C program:
Line Feed (LF, 0x0A)
- Old Mac (OS 9 and before):
Carriage Return (CR, 0x0D)
- Web (e.g. HTML):
all three possible
C on Windows: automatic conversion between CRLF (in file) and LF (in
program)
入出力の主な関数
|
入力 |
出力 |
一文字 |
getchar() |
putchar(char c) |
一行 |
gets(char* buffer)
fgets(char*, int, stdin) |
puts(char* string) |
フォーマット付き |
scanf(char* format,...) (%s ) |
printf(char* format,...) |
関数の学習
- 優先度
- 関数の存在
- 大体の機能や用途
- 名前
- 詳細な仕様 (戻り値を含む)
- 情報の入手方法
入出力関数の戻り値
getchar
: 文字 (の番号) 又は EOF
(end of
file, ファイルの終わり)
putchar
: 出力した文字またはエラーの場合
EOF
fgets
:
バッファ又は何も読んでない場合、NULL
puts
: 負でない整数または EOF
scanf
: 読み込みに成功した変数の数または
EOF
printf
: 出力した文字の数
入力の定石
- プログラムにはよく出てくるパターン (定石)
が存在
- これはプログラム言語の「言い回し」(idiom, pattern)
- 文法の勉強だけではなく、定石の勉強も大事
- ただ使うだけではなく、理解するのが大事
具体例:
while ((c = getchar()) != EOF) { ... }
Buffer Overflow
C 言語のメモリの扱い:
- あるプログラムに与えられたメモリは勝手に使ってよい
(プログラマの責任)
- 他のプログラムが使用するメモリは使用不可能
(
Segmentation Fault
などのエラー)
例: int array[10]; array[20] =
100;
- プログラム内はプログラマの責任で対応可能
- 入力 (特に一行入力) の場合は予想が不可能
- 不注意は多くのバグ (bug) と脆弱性 (vulnerability)
の原因
gets
の問題点
- 多くの教科書・参考書ではまだ使用中
- 入力の長さは予想不可能
- バッファの長さが足りないと他の変数などが勝手に書き換えられる
- 本実習で禁止
- C99
の標準で非推奨、C11
で標準から除去
(演習問題 04B1 参照)
scanf
の要点
例: scanf ("%lf", &doubleVar);
printf
と少々書き方が違う
%s
は gets
と同様に大問題 (演習問題 04B1 参照)
標準入出力
- 入力一つ、出力一つのプログラムが非常に多い
- これらは「標準入力」(standard input,
stdin
)
と「標準出力」(standard output, stdout
)
と呼ばれる
- C のプログラムではこれらは常に準備されている
- 標準入力はどこから、標準出力はどこへかはプログラムではなく、環境で決定
- 環境は普通標準入力がキーボードから、標準出力は画面へと設定
- ファイルとデバイス (キーボード、画面)
を同等に扱う考え方は Unix で生まれた
リダイレクトとパイプ
- リダイレクト (redirect)
によって、標準入出力の「交通整理」が可能
- 入力のリダイレクト (ファイルからの入力)
例: $ ./prog1 <inputfile.txt
- 出力のリダイレクト (ファイルへの出力)
例: $ ./prog1 >outputfile.txt
- 入力と出力のリダイレクトの組み合わせ
例: $ ./prog1 <inputfile.txt >outputfile.txt
- あるプログラムの出力と次のプログラムの入力の接続
(パイプ、pipe)
例: $ prog1 | prog2
標準入出力の応用
- キーボード入力の手間の省略
- 出力の保存、分析
- ファイルの簡単な処理
- 複数の簡単なプログラムの組み合わせによる強力な処理
- プログラムのテスト
標準入出力によるプログラムのテスト
- 入力の例のファイル (例えば
04A1in.txt
)
を用意
- 期待される出力のファイル (
04A1check.txt
)
を用意
- プログラムをリダイレクトで実行、出力を別のファイル
(
04A1out.txt
) に保存
$ gcc 04A1.c && ./a <04A1in.txt
>04A1out.txt
- 実際の出力と期待された出力を比較 (
diff
コマンドで)
$ diff 04A1out.txt 04A1check.txt
(出力が二つのファイルの差分なので、出力がなかったら成功)
- コンパイル・実行・比較を一行で総括
$ gcc 04A1.c && ./a <04A1in.txt |
diff - 04A1check.txt
(出力がない場合、テストが成功)
Why Tests?
- Smoth development with small steps
- Base for talking with customer
- First step towards a specification document
- Early detection of bugs
- Best for regression tests
(check that a change in one part of a program doesn't produce bugs in other
parts of the program)
- Very important in practice
今週の演習問題
04A1: 一文字の入力と出力 ('\''
は \
の文字列ではなく、'
一文字 (\
でエスケープ))
04A2: 文字の番号の調査
04A3: 大文字と小文字の入れ替え
04B1: バグの入ったプログラムの分析と修正
(今日必ず先生に提出)
04B2: 様々な型の入出力 (教科書 pp. 385-387 参照)
04C1 (部分点): ヒント:
入力の一文字ずつ枝分かれを使うか、小さいバッファーに一文字ずらしながら読み込むなど
挑戦 (部分点)
は必須、完成は発展問題、月曜日締切
次回の準備
- 宿題として残りの演習課題の完成・提出
- 今日の復習
- 教科書の第 8 章 (関数、pp. 179-203) と第 9 章 (復習:
配列) を読む
Glossary
- rolling pin
- 麺棒
- principle
- 原則
- function
- 関数
- string
- 文字列
- byte array
- バイトの配列
- interpret
- 解釈する
- null character
- ナル文字
- input
- 入力
- output
- 出力
- buffer overflow
- バッファ・オーバーフロー
- standard input/output
- 標準入出力
- specification (document)
- 仕様 (書)
- bug
- バグ
- regression test
- 退行テスト、回帰テスト、再帰テスト