gets関数は、stdio.hをインクルードすれば、利用できます。
しかし正しく利用するには、その関数がどのように作られたものかを理解する必要があります。
以下では、この関数の定義例と利用例を紹介します。
引数sが指し示す記憶域へ、標準入力から入力した1行の文字列を記憶する関数です。
1行とは、「Enter」を押すまでの文字列での中にスペースやタブを含めた入力が可能です。
エラーなく実行できた時は、実引数の値を返します。ポインタを返す関数は、一般的に失敗時にNULLを返し、この関数もそうです。
以下に、配列演算子を使った定義例と使用例を示します。
(c = getchar())で入力した文字コードをcに記憶させ、その記憶内容が、getcharのエラー
コード(EOF)でない間、pが指し示す記憶域へ先頭byteから順次に記憶する繰り返しになっています。
#include <stdio.h> char *gets(char *s) /* ←この1行を char *gets(char s[]) と書いても、実はまったく同じ! */ { int c;/* 入力コード記憶用 */ int i = 0; while( (c = getchar()) != EOF) { s[i] = c; if(s[i] == '\n'){ s[i] = '\0';/* 文字列終端コードをセット */ return s; } i++; } return NULL;/* エラーのリターン */ } main() { char buf[10]; char *str; str = gets( buf ); /* 1行入力 */ puts( str ); /* 入力した文字列を表示 */ }
以下に実行例を示します。単にスペースを含めた1行を入力して、表示しています。 (赤が入力)
12 abc 12 abc
なお、上記の仮引数の宣言char *sは、ポインタ宣言子を使わう代わりに、
配列宣言子でchar s[]と書いてもまったく同じです。
[ と ] の間に、数字は書きません
このように配列宣言子を仮引数の宣言に使っても、実質的にポインタ変数になる仮引数
を宣言していることになります。(よって後述するような変更も可能です)
これは、仮引数の宣言だけに適用される例外規則で、通常の変数では、そうなりません
(配列は指定の要素を並べた記憶域先頭アドレスで定数と同じ扱いで変更できない)。
次は、上記のプログラムとまったく同じ機能を、ポインタ変数を変更するプログラミングで作った例です。
(配列演算子[]の代わりにポインタ演算子*を使っています)
どちらが良いか?というものではありません。しかし、次のポインタ変数を変更するC言語独特のタイプを好む人がいるのは
事実です。
(この作り方の方が、少し速い動作をするマシン語へ翻訳するコンパイラが存在して、それを意識する時代がありました)
#include <stdio.h> char *gets(char s []) /* ←この1行を char *gets(char *s) と書いても、実はまったく同じ! */ { int c;/* 入力コード記憶用 */ char * p = s; while( (c = getchar()) != EOF) { *p = c; if(*p == '\n'){ *p = '\0'; return s; } p++; } return NULL; } main() { char buf[10]; char *str; str = gets( buf ); /* 1行入力 */ puts( str ); /* 入力した文字列を表示 */ }
進む順番で説明します。⇒
(step1)
標準入力バッファの記憶内容を以下に示す。 (データが記憶される範囲をこの色で示す)
上記が実行画面