プログラム これを実行 すると… 問題のあるプログラム 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は使わない
© Copyright 2024 ExpyDoc