Document

プログラム
これを実行
すると…
問題のあるプログラム
2番目の文字が
入力できない
文字がcのサイズより
多くてもエラーが出ない
プログラムの問題点
1. バッファサイズのチェックを行っていない
2. 空白、改行も入力文字として取っている
3. 型をチェックしていない
scanfを使わない入力

CRT(C Runtime)には、ストリームが用意されている
ストリームとは
プログラム、入出力先間のデータの流れの経路

ストリームの種類
ポインタ
ストリーム
機能
FILE* stdin
標準入力
キーボードから読み込み
FILE* stdout
標準出力
画面へ出力
FILE* stderror
標準エラー出力
画面へ出力
1の改善策:入力関数

ファイルから一行読み込む関数
char* fgets(char* str, int str_size, FILE* fp);
ヘッダ <stdio.h>
[返り値]char* str
fpにストリームをセットすることで
ストリームから文字列を読み取りstrが指す配列に格納する
なお、格納されるのは (str_size – 1) バイト目まで
2の改善策:バッファ削除

標準入力(stdin)から1文字入力する関数
int getchar();
ヘッダ <stdio.h>
[返り値] その文字コードを返す
入力ストリームに残っている場合は、
入力を行うのではなく、入力ストリームから1文字取り出す
※入力が改行で終わるとき、次の方法でできる
char str[20];
fgets(str, sizeof(str) stdin);
int strLength = strlen(str); //strlen() : 文字列の長さを取得する
if (str[strLength - 1] != ‘\n’){
// 改行がでるまで標準入力から1文字ずつ取り出す
while(getchar() != '\n');
}
2の改善策:バッファ削除

バッファのフラッシュ(消去)を行う

Borland C++ Compiler(bcc)のみ使える方法(※)
int fflush(FILE* stream);
ヘッダ <stdio.h>
[返り値] 0
streamが出力ストリーム、または
直前の操作が入力でない入出力ストリームなら
全ての内容を出力し、消去する
※ Borland C++ Compiler(bcc)では、上記の機能に加えて
streamが入力ストリームなら全て内容を消去するという機能がある
[ 注意 ]
標準規格(ANSI-C)では、入力ストリームに対しての動作は未定義である
3の改善策:フォーマット関数

文字列から書式指定に従い入力を行う関数
int sscanf(const char* str, const char* format, [argument]);
ヘッダ <stdio.h>
[返り値]代入された入力項目の個数
str の文字列を format の形式に変換し、
指定した変数のアドレスに代入
改善したプログラム
プログラムの解説
fgets(d,sizeof(d),stdin);
[0]
d
[1]
[2]
[3]
[4]
\0
stdin
a
ヌル文字を入れる
d – 1 バイト目まで文字列を入れていく
b
c
d
e
f
\n
プログラムの解説
if(d[strlen(d) - 1] != ‘\n’)
d
[0]
[1]
[2]
[3]
[4]
a
b
c
d
\0
stdin
strlen = 4
strlen(d) – 1 番目が \n か判定
dの文字列の長さを求める(\0は含まない)
e
f
\n
プログラムの解説
while(getchar() != ‘\n’);
d
[0]
[1]
[2]
[3]
[4]
a
b
c
d
\0
getchar
取り出した文字が
stdinから1文字取り出す
\n を取り出すまで繰り返す
\n か判定
stdin
e
f
\n
プログラムの解説
if(sscanf(d,”%s”,c) == 0) exit(-1);
d
[0]
[1]
[2]
[3]
[4]
a
b
c
d
\0
cd を文字列型に変換
に文字列型に変換した d をコピー
c
[0]
[1]
[2]
[3]
[4]
a
b
c
d
\0
課題3
5個の変数にそれぞれ整数を入力し、引数が
1つの関数ポインタを利用してその値を加算
せよ
scanfは使わない