C言語のコンソール入出力基本パターン1

### 基本用法
– 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()を作ったのだろうか
プログラムの脆弱性をつくプログラマーも相当ロジカルでないと務まらんな