LoginSignup
1
0

More than 5 years have passed since last update.

getsを使って安全に入力を得る

Posted at

一般に、C言語でgetsを使うことは危険だと言われています。

危険なコードは書きたくないが、万が一課題などでどうしてもgetsを使わなければならないとしたら、どうすればいいでしょうか?

使えばいいのです。あくまで標準ライブラリのgets関数が危険なのであって、getsというトークン自体には何の危険性もありません。

以下にgetsを使ったサンプルコードを示します。

use_gets.c
#include <stdio.h>

/* 行を読み込んだら真、読み込めなかったら偽を返す */
int read_line(char *b, size_t s) {
    size_t gets = 0;
    if (s == 0) return 0; /* バッファが0バイトしかなかったら、読み込めない */
    for (;;) {
        int c = getchar();
        if (c == EOF) {
            b[gets] = '\0';
            return gets > 0; /* 1文字以上入力していたら有効な入力、0文字なら入力なしと判定する */
        } else if (c == '\n') {
            b[gets] = '\0';
            return 1;
        } else {
            b[gets++] = (char)c;
            if (gets + 1 >= s) {
                /* バッファがいっぱいになるので、その場で読み込みを打ち切る */
                b[gets] = '\0';
                return 1;
            }
        }
    }
}

int main(void) {
    char line[20];
    int count = 1;
    while (read_line(line, sizeof(line))) {
        printf("%d: %s\n", count++, line);
    }
    return 0;
}

入力例

0123456789012345678901234567890
abcdefg
hijklmnopqrstuvw
xyz

この入力例に対する出力

1: 0123456789012345678
2: 901234567890
3: abcdefg
4: hijklmnopqrstuvw
5: xyz

出力の内容はともかく、きちんとバッファオーバーランが回避できています。

1
0
1

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
1
0