### 基本用法
– getchar(), gets(), scanf()は「標準入力」(キーボード)から入力
– putchar(), puts(), printf()は「標準出力」(ディスプレイ)に出力
int main(void){
int ch; // 変数確保
ch = getchar();
putchar(ch); // 入力文字を画面に出力
return 0;
}
$ ./dev
hello
h
※getchar()関数はキーボードから1文字を入力する
### 連続文字入力
#include <stdio.h>
#include <ctype.h> /* for toupper() */
int main(void){
int ch; // 変数確保
ch = getchar();
while (ch != EOF){
ch = toupper(ch);
putchar(ch);
ch = getchar();
}
return 0;
}
$ ./dev
hello
HELLO
※EOFはend of fileで、[ctl]+[z]で終了。
※バッファリング処理で、内部バッファで1行単位で読み込み、内部的に1文字ずつ処理している。
### 1行入出力
int main(void){
char s[80];
gets(s);
puts(s);
return 0;
}
$ ./dev
abc def
abc def
gets()はキーボードから文字列を1行入力する為の関数
puts()はディスプレイに文字列を出力する為の関数
– 文字列だけしか出力できない
– 文字列を出力した後、自動的に改行を行う
hello.c:(.text+0x24): warning: the `gets’ function is dangerous and should not be used.
gets()関数の配列オーバーに対する危険性は広く認識されている。C11では安全なgets_s()関数が使えるようになっている。
### 連続文字列入力
int main(void){
char s[80];
while (gets(s) != NULL){
puts(s); puts(s);
}
return 0;
}
$ ./dev
abcde
abcde
abcde
XYZ
XYZ
XYZ
[ctl]+[z]でNULLを返す。NULLの値はstdio.hの中で定義されている
int main(void){
char s[80];
while(1) {
gets(s);
if (strcmp(s, ".") == 0) break;
printf("input char is %s.\n", s);
}
return 0;
}
strcmp()は文字列を比較する関数
### 整数値の入出力
int main(void){
int n;
scanf("%d", &n);
printf("%d\n", n);
return 0;
}
scanf()関数はキーボードから色々なデータを入力する機能をもつ。
scanf(“%d”, &n)は、変数のアドレスを記述する
double ddt;
scanf(“%lf”, %ddt);
printf(“%f\n”, ddt);
scanf()は数値入力のみ受け付ける
int main(void){
int n = 9999;
scanf("%d", &n);
printf("number is %d\n", n);
return 0;
}
gets()関数で文字列として受け取って、atoi()関数で整数に変換という方法もある
不動小数点の場合はatof()
int main(void){
int n;
char s[80];
gets(s);
n = atoi(s);
printf("number is %d.\n", n);
return 0;
}
scanf や fgetsは、格納先に入力できる最大長を指定することでバッファオーバーランを回避することができる
getsは入力される文字列の長さを制限する機能が存在しない
C言語の設計者は、配列格納とは異なる意図でgets()を作ったのだろうか
プログラムの脆弱性をつくプログラマーも相当ロジカルでないと務まらんな