キーボードから文字入力

入力を 1 文字単位で取得

getchar.c

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
/*
  stdio.h [getchar]

  書式: int getchar (void)
  機能: 標準入力 (キーボード) から入力された 1 文字を取得
  引数: なし
  戻り値: 成功すると, 入力された文字を返し,
          失敗すると, EOF(-1) を返す.
*/

/*
  getchar() は, デバッグにも使われている,
  ちょっとプログラムを止めたいコードの場所に,
  getchar() を入れとくとそこで止まってくれる.
*/

#include <stdio.h>

int main(void){
  int c;
  int i = 0;

  printf("文字を入力してください\n");
  printf("ENTERキーで確認する\n");

  while( (c = getchar()) != EOF ){
    printf("%02d:%c\n", i++, c);
  }
  
  return 0;
}

getchar.c の実行結果は:

[cactus:~/code_c/refer]% ./getchar
文字を入力してください
ENTERキーで確認する
wtopia
00:w
01:t
02:o
03:p
04:i
05:a
06:

[cactus:~/code_c/refer]%

入力を 1 行単位で取得

gets.c

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
/*
  stdio.h [gets]

  書式: char *gets(char *s)
  機能: 標準入力 (キーボード) から入力を 1 行単位でを取得
  引数: char *s: 1 行を取得するためのバッファ (配列) を指定
  戻り値: 成功すると, 文字列を返し,
          失敗すると, NULL を返す.
*/

/*
  gets() で文字を受け取るには, 文字列を入力した最後に改行
  (ENTERキー) を押す. 受け取る文字列の中には, 改行文字は
  入ってない.
  また, 文字列の最後に "\0" が入っているため, バッファサイズ
  は [文字数 + 1] が必要である.
*/

#include <stdio.h>

int main(void){
  char s[11]; /* 文字数 + 1 のサイズ */
  
  printf("10 文字以内で入力してください\n");
  printf("ENTERキーで確認する\n");

  gets(s);
  printf("受け取った文字列: %s\n", s);
  
  return 0;
}

gets.c の実行結果は:

[cactus:~/code_c/refer]% ./gets
10 文字以内で入力してください
ENTERキーで確認する
warning: this program uses gets(), which is unsafe.
wtopia
受け取った文字列: wtopia

入力を書式付きで取得

scanf.c

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
/*
  stdio.h [scanf]

  書式: int scanf(const char *format, ...)
  機能: キーボードからの入力を書式付きで取得
  引数: ...: 可変個引数で書式で指定された変数のアドレスを
        カンマ区切りで指定する.
  戻り値: 成功すると, 入力項目数を返し,
          失敗すると, EOF(-1) を返す.
*/

#include <stdio.h>

int main(void){
  int i;
  char s[100]; /* 文字列用 */

  printf("10 進数で入力:");
  scanf("%d", &i);
  printf("入力文字:%d\n\n", i);

  printf("16 進数で入力:");
  scanf("%x", &i);
  printf("入力文字:%d\n\n", i);

  printf("文字列を入力:");
  scanf("%s", s);
  printf("入力文字:%s\n\n", s);

  return 0;
}

scanf.c の実行結果は:

[cactus:~/code_c/refer]% ./scanf
10 進数で入力:10
入力文字:10

16 進数で入力:0x11
入力文字:17

文字列を入力:wtopia
入力文字:wtopia

ストリームに 1 文字戻す

ungetc.c

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
/*
  stdio.h [ungetc]

  書式: int ungetc(int c, FILE *fp)
  機能: 読み込んだ文字をストリームに 1 文字戻す
  引数: int c: 押し戻したい 1 文字
        FILE *fp: ファイルポインタ (ストリーム)
  戻り値: 成功すると, 押し戻した 1 文字を返し,
          失敗すると, EOF(-1) を返す.
*/

/*
  文字列を分解する際に, 判定用の文字を 1 度読み込んだ後,
  もう一度ストリームに戻してから改めて処理できるため,
  便利なのだ.
*/

/*
  ファイルから 'A' を 1 文字読み込んだ後, ungetc() で
  1 文字戻し, 再度 1 文字を読み込んでみる.
*/

#include <stdio.h>

int main(void){
  FILE *fp;
  char *fname = "test.txt";
  int c;

  fp = fopen(fname, "r");
  if(fp == NULL){
    printf("%sファイルが開けない\n", fname);
    return 0;
  }
  
  c = fgetc(fp);
  printf("1 文字を読み込む%c\n", c);

  ungetc(c, fp); /* 1 文字戻す */

  c = fgetc(fp);
  printf("再度読み込む%c\n", c);

  fclose(fp);

  return 0;
}

ungetc.c の実行結果は:

[cactus:~/code_c/refer]% ./ungetc
1 文字を読み込むa
再度読み込むa