
C言語の基本|C言語の文字列入出力の基本
行の言葉を安全に受け取り、そのまま画面へ届けよう。fgetsとputsから始める文字列入出力の第一歩
C言語で1文字を入力するgetcharや、1文字を出力するputcharの使い方が分かってくると、次に必要になるのが文字列の入出力です。
名前、住所、感想、商品名、短いメッセージなど、実際のプログラムでは複数の文字をひとまとまりとして扱う場面がたくさんあります。
1文字ずつgetcharで読み取り、自分で配列へ格納することもできます。しかし、1行分の文字列を入力したいだけなのに、毎回繰り返し処理や配列の添字を細かく管理するのは大変です。
このような場面で役立つのがfgetsです。
fgetsを使うと、読み込む大きさを指定しながら、空白を含む1行分の文字列を配列へ格納できます。読み込んだ文字列を表示するときは、putsを利用すると簡単です。
putsは、指定した文字列を標準出力へ書き込み、最後に改行を追加します。文字列をそのまま1行表示したい場合に使いやすい関数です。
文字列の入力にはscanfと%sを使う方法もあります。しかし、scanfと%sの組み合わせでは、一般的に空白が入力の区切りとして扱われます。そのため、空白を含む文章全体を読み取りたい場合はfgetsが適しています。
ここでは、次の内容を順番に見ていきます。
- 文字列を入出力するという考え方
- fgetsの引数と戻り値
- fgetsが文字列を読み終える条件
- scanfとfgetsの違い
- putsの動作と戻り値
- fgetsで読み込まれる改行文字
- putsによって改行が追加される仕組み
- 文字列末尾の改行を取り除く方法
- EOFまで文字列入力を繰り返す方法
fgetsとputsには、配列、文字列、ナル文字、改行文字、EOF、NULLなど、C言語の文字列処理に欠かせない要素が含まれています。基本から順番に確認していきましょう。
文字列を入出力するとは
文字列の入出力とは、複数の文字が連続したデータを、ひとまとまりとして読み込んだり表示したりすることです。
例えば、次のデータはすべて文字列です。
- おはようございます
- C言語を学習しています
- 2026年8月
- Hello World
- Product Number 315
12345のように数字だけで構成されていても、文字の並びとして扱う場合は文字列です。
C言語には、文字列専用の基本型はありません。文字列は、char型の配列へ複数の文字を並べ、最後にナル文字を置くことで表現します。
例えば、Helloという文字列は、配列の中で次のように格納されます。
'H' 'e' 'l' 'l' 'o' '\0'最後のナル文字は、文字列がどこで終わるのかを表します。
文字列を安全に入出力するには、次の点を意識する必要があります。
- 文字列を格納する配列の大きさ
- 読み込む文字数の上限
- 文字列の末尾に置かれるナル文字
- Enterによって入力される改行文字
- 入力に成功したかどうかを表す戻り値
fgetsはこれらを意識しながら、文字列を配列へ読み込むための関数です。
1文字の入出力と文字列の入出力
1文字だけを扱う場合と、文字列全体を扱う場合では、適した関数が異なります。
| 処理したい内容 | 入力関数 | 出力関数 |
|---|---|---|
| 1文字 | getchar | putchar |
| 1行の文字列 | fgets | puts |
| 書式を指定したデータ | scanf | printf |
getcharとputcharは1文字単位で処理します。fgetsとputsは、ナル文字で終わる文字列をひとまとまりとして扱います。
文字列を1文字ずつ処理したい場合はgetcharやputcharも役立ちます。しかし、入力した文章をまとめて配列へ格納したい場合は、fgetsを使うほうが簡潔です。
図1:1文字の入出力と文字列の入出力

この図から分かること
getcharとputcharは、1文字ずつ入出力する関数です。fgetsとputsは、複数の文字からなる文字列をまとめて扱うために利用できます。
fgetsで読み込んだ文字列は、char型の配列へ格納されます。Enterまで読み込めた場合は改行文字も入り、その後ろに文字列の終わりを表すナル文字が置かれます。
処理したいデータが1文字なのか、1行の文字列なのかを考えて関数を選ぶことが大切です。
fgets関数とは
fgetsは、指定した入力ストリームから文字列を読み取り、char型の配列へ格納する関数です。
ファイルから文字列を読み取るときにも使えますが、第3引数にstdinを指定すると、標準入力から文字列を読み取れます。一般的な対話型の実行環境では、標準入力はキーボードに接続されています。
fgetsを使うにはstdio.hをインクルードします。
#include <stdio.h>fgetsの関数宣言は次のとおりです。
char *fgets(char *restrict s, int n, FILE *restrict stream);最初は複雑に見えるかもしれませんが、戻り値と3つの引数に分けると理解しやすくなります。
fgetsの引数
fgetsは3つの引数を受け取ります。
| 引数 | 役割 |
|---|---|
| s | 読み込んだ文字列を格納する配列の先頭 |
| n | 配列へ格納する文字数の上限を決める値 |
| stream | 文字列を読み取る入力元 |
キーボードから文字列を入力し、messageという配列へ格納する場合は、次のように書きます。
char message[100];
fgets(message, sizeof(message), stdin);それぞれの引数には、次の内容を指定しています。
| 指定した内容 | 意味 |
|---|---|
| message | 入力した文字列を格納する配列 |
| sizeof(message) | message全体の大きさ |
| stdin | 標準入力から読み取る |
配列名messageは、式の中では多くの場合、配列の先頭要素を指すポインタとして扱われます。そのため、fgetsはmessageの先頭から文字列を書き込めます。
第1引数sの役割
第1引数sには、読み取った文字列を格納する領域の先頭を指定します。
char message[100];
fgets(message, sizeof(message), stdin);この例では、入力した文字列がmessageへ格納されます。
fgetsを呼び出す前に、文字列を格納できるchar型の配列を用意しておく必要があります。
第2引数nの役割
第2引数nには、読み込み先として使用できる配列の大きさに合った値を指定します。
fgets(message, sizeof(message), stdin);messageが100要素のchar型配列であれば、sizeof(message)は100になります。
fgetsは、最大でもn-1文字までを配列へ格納し、その後ろにナル文字を付けます。
n文字すべてを入力データに使わない理由は、文字列の末尾にナル文字を格納するための1要素が必要だからです。
配列の大きさが10の場合は、次のようになります。
| 内容 | 最大数 |
|---|---|
| 入力から読み込める文字 | 9文字 |
| 末尾に格納するナル文字 | 1文字 |
| 配列全体 | 10文字分 |
配列の大きさを直接100と書くこともできます。
fgets(message, 100, stdin);ただし、配列名と同じ場所でsizeofを使うと、後から配列の大きさを変更した場合でも修正箇所を減らせます。
fgets(message, sizeof(message), stdin);この書き方では、messageの実際の大きさをfgetsへ渡せます。
第3引数streamの役割
第3引数streamには、入力元となるストリームを指定します。
キーボードからの標準入力を使う場合は、stdinを指定します。
fgets(message, sizeof(message), stdin);stdinは標準入力を表します。一般的な実行環境では、キーボードから入力されたデータを読み取るために使われます。
fgetsは、標準入力だけに限定された関数ではありません。ファイルを表すストリームを指定すれば、ファイルから1行ずつ文字列を読み取ることもできます。
ここでは、stdinを指定してキーボードから文字列を入力する基本を確認します。
restrictの基本的な考え方
fgetsの関数宣言にはrestrictが含まれています。
char *fgets(char *restrict s, int n, FILE *restrict stream);restrictはC99で導入されたキーワードです。
これは、関数が処理している間、対象となるデータへアクセスするポインタの関係について一定の約束を示し、コンパイラが最適化しやすくするために使われます。
fgetsを使い始める段階で、restrictの細かな規則をすべて理解する必要はありません。
まずは次の点を押さえておけばよいでしょう。
- sには文字列を格納する配列を指定する
- nには配列の大きさに合った値を指定する
- streamには入力元を指定する
- キーボード入力ではstdinを指定する
fgetsはどこまで読み込むのか
fgetsは、次のいずれかの条件が成立するまで文字を読み取ります。
- 改行文字を読み取った
- n-1文字を読み取った
- EOFを検出した
| 読み込みを終える条件 | 動作 |
|---|---|
| 改行文字を読み取った | 改行文字を配列へ格納して読み込みを終える |
| n-1文字を読み取った | そこで読み込みを止め、最後にナル文字を付ける |
| EOFを検出した | それまでに文字を読み取っていれば、その文字列を返す |
| 1文字も読む前にEOFを検出した | NULLを返す |
| 入力エラーが発生した | NULLを返す |
改行文字を読み取って終了した場合、その改行文字も配列に格納されます。
例えば、Catと入力してEnterを押した場合、十分な大きさの配列があれば、次のように格納されます。
'C' 'a' 't' '\n' '\0'文字列の最後には、fgetsによってナル文字が追加されます。
入力が配列より長い場合
fgetsは、配列へ格納できる範囲を超えて文字を読み込みません。
例えば、配列の大きさが5の場合、入力から読み取れるのは最大4文字です。残りの1要素にはナル文字が格納されます。
char text[5];
fgets(text, sizeof(text), stdin);ABCDEFGと入力した場合、最初のfgetsでは次の部分が格納されます。
'A' 'B' 'C' 'D' '\0'まだ読み取られていないEFGと改行文字は、標準入力側に残ります。続けてfgetsを呼び出すと、残っている文字が読み取られます。
fgetsが配列の範囲を超えて書き込まないことは大きな利点ですが、長い入力が分割される可能性があることにも注意が必要です。
図2:fgetsが文字列を配列へ格納する流れ

この図から分かること
fgetsは、入力した文字列をchar型の配列へ順番に格納します。
改行文字まで読み取れた場合は、その改行文字も配列に入ります。読み込みに成功した文字列の末尾には、文字列の終わりを表すナル文字が付けられます。
配列の大きさがnの場合、入力から読み取れる文字は最大n-1文字です。残りの1要素はナル文字のために使われます。
fgetsは改行文字、n-1文字、EOFのいずれかをきっかけとして読み込みを終了します。
scanfとfgetsの違い
文字列は、scanfと%sを使って入力することもできます。
char word[20];
scanf("%19s", word);しかし、scanfと%sでは、空白文字が入力の区切りとして扱われます。
例えば、次の1行を入力したとします。
C language is funscanfと%sでは、最初の空白までにあるCだけがwordへ格納されます。
一方、fgetsでは、配列に十分な大きさがあれば、空白を含む1行をまとめて読み取れます。
char line[100];
fgets(line, sizeof(line), stdin);scanfとfgetsの主な違いは次のとおりです。
| 比較項目 | fgets | scanfと%s |
|---|---|---|
| 空白を含む入力 | 空白を含めて読み取れる | 空白で区切られる |
| 改行文字 | 配列に入ることがある | 読み取った文字列には入らない |
| 読み込み方 | 1行単位に近い | 単語単位に近い |
| 大きさの指定 | 第2引数で指定する | 変換指定に幅を指定する必要がある |
| 戻り値 | 成功時は配列の先頭、失敗時などはNULL | 正常に変換できた項目数を返す |
名前や文章など、空白を含む入力を扱う場合はfgetsが使いやすいでしょう。
scanfにも適した場面はありますが、1行の文字列を読み込みたいときはfgetsを選ぶと処理の目的が明確になります。
fgetsの戻り値
fgetsは、文字列の読み込みに成功したかどうかを戻り値で知らせます。
| 状態 | 戻り値 |
|---|---|
| 1文字以上の読み込みに成功した | 第1引数で指定した配列の先頭 |
| 1文字も読まずにEOFへ到達した | NULL |
| 入力エラーが発生した | NULL |
fgetsの戻り値は、次のように確認できます。
if (fgets(message, sizeof(message), stdin) != NULL) {
/* 読み込みに成功した場合 */
} else {
/* EOFまたは入力エラーの場合 */
}fgetsの戻り値を確認せずに配列を使うと、読み込みに失敗していた場合に正しい文字列を扱えません。
入力後は、fgetsの戻り値がNULLではないことを確認する習慣をつけましょう。
NULLとは
NULLは、ポインタが有効な場所を指していないことを表すために使われます。
fgetsの戻り値の型はchar型へのポインタです。読み込みに成功した場合は、文字列を格納した配列の先頭を返します。
読み込みに失敗した場合や、1文字も読み込まずにEOFへ到達した場合はNULLを返します。
| fgetsの戻り値 | 意味 |
|---|---|
| messageなどの配列の先頭 | 読み込みに成功した |
| NULL | 読み込みに成功しなかった |
EOFは入力の終わりを表す特別な整数値です。一方、NULLは有効な場所を指していないことを表すポインタの値です。
fgetsはポインタを返す関数なので、戻り値の判定にはEOFではなくNULLを使います。
puts関数とは
putsは、指定された文字列を標準出力へ書き込む関数です。
putsを使うにはstdio.hをインクルードします。
#include <stdio.h>putsの関数宣言は次のとおりです。
int puts(const char *s);putsは、sが指している文字列を標準出力へ書き込み、最後に改行を追加します。
例えば、次のように使用します。
puts("C言語を学習しています。");実行すると、文字列が表示された後、表示位置が次の行へ移動します。
C言語を学習しています。putsの引数と戻り値
putsの引数と戻り値は次のとおりです。
| 項目 | 内容 |
|---|---|
| 引数 | 出力する文字列の先頭 |
| 戻り値の型 | int型 |
| 正常終了時 | 非負の値 |
| 出力エラー時 | EOF |
putsの引数には、ナル文字で終わる文字列を指定します。
putsは文字列内のナル文字までを出力しますが、ナル文字そのものは画面へ出力しません。その代わり、文字列の表示後に改行を追加します。
putsとprintfの違い
putsとprintfはどちらも文字列を出力できますが、得意な処理が異なります。
| 関数 | 特徴 |
|---|---|
| puts | 文字列をそのまま表示し、最後に改行を追加する |
| printf | 書式を使って文字列や数値を柔軟に表示する |
文字列だけを1行表示したい場合はputsが簡潔です。
puts(message);文字列と数値を組み合わせたい場合や、表示形式を調整したい場合はprintfが適しています。
printf("入力された文字列は%sです。\n", message);putsは自動的に改行を追加しますが、printfは書式文字列に改行を指定しなければ改行しません。
文字列を入力して表示するプログラム
fgetsとputsを使い、キーボードから入力した1行の文字列を表示してみましょう。
入力した予定を案内文と一緒に表示するプログラム
ファイル名:12_4_1.c
#include <stdio.h>
int main(void)
{
char schedule[100];
puts("今日の予定を入力してください。");
/* 標準入力から1行読み込む */
if (fgets(schedule, sizeof(schedule), stdin) != NULL) {
puts("入力された予定です。");
puts(schedule);
} else {
puts("予定を読み取れませんでした。");
}
return 0;
}実行結果の例
午後に図書館でC言語を勉強しますと入力した場合の例です。
今日の予定を入力してください。
午後に図書館でC言語を勉強します
入力された予定です。
午後に図書館でC言語を勉強します入力内容を表示した後に空行が入ったように見える理由は、後ほど詳しく確認します。
文字列を入力して表示するプログラムの解説
文字列を格納する配列
char schedule[100];入力した文字列を格納するために、char型の配列scheduleを用意しています。
配列には最大100文字分の領域があります。ただし、文字列の末尾にはナル文字が必要なので、fgetsが入力から格納できるのは最大99文字です。
入力案内を表示する部分
puts("今日の予定を入力してください。");putsで入力案内を表示しています。
putsは文字列の表示後に改行を追加するため、次の行から入力できる状態になります。
1行の文字列を読み込む部分
fgets(schedule, sizeof(schedule), stdin)fgetsへ次の3つの引数を渡しています。
| 引数 | 指定内容 |
|---|---|
| 第1引数 | schedule |
| 第2引数 | sizeof(schedule) |
| 第3引数 | stdin |
scheduleは読み込み先の配列、sizeof(schedule)は配列全体の大きさ、stdinは標準入力を表します。
戻り値を確認する部分
if (fgets(schedule, sizeof(schedule), stdin) != NULL) {fgetsの戻り値がNULLではないかを確認しています。
NULLでなければ読み込みに成功したため、if文の中で入力内容を表示します。NULLの場合は、EOFまたは入力エラーによって文字列を読み取れなかったと判断します。
入力内容を表示する部分
puts("入力された予定です。");
puts(schedule);最初のputsで案内文を表示し、次のputsでscheduleに格納されている文字列を表示します。
scheduleの中に改行文字が含まれている場合、その改行に加えてputsも改行を追加します。その結果、表示後に空行が入ったように見える場合があります。
読み込みに失敗した場合
else {
puts("予定を読み取れませんでした。");
}fgetsがNULLを返した場合は、入力を読み取れなかったことを示すメッセージを表示します。
入力が成功した場合と失敗した場合を分けることで、読み込み結果を確認しながら処理できます。
改行が余分に入る理由
fgetsとputsを組み合わせると、文字列の表示後に空行が入ったように見えることがあります。
これは、fgetsとputsの両方が改行に関係しているためです。
| 関数 | 改行の扱い |
|---|---|
| fgets | Enterによる改行文字を配列へ格納することがある |
| puts | 文字列を出力した後に改行を追加する |
例えば、Helloと入力してEnterを押すと、十分な大きさの配列には次のように格納されます。
'H' 'e' 'l' 'l' 'o' '\n' '\0'この文字列をputsで表示すると、次の2つの改行が続きます。
- scheduleに含まれている改行文字
- putsが自動的に追加する改行
処理のイメージは次のとおりです。
Hello
↑ fgetsが読み込んだ改行
↑ putsが追加した改行このため、文字列を表示した後に空行が1行入ったように見えます。
図3:fgetsとputsで改行が重なる仕組み

この図から分かること
fgetsでEnterまで読み取れた場合、入力された文字列には改行文字が含まれます。その文字列をputsへ渡すと、文字列内の改行に加えて、putsがもう1つ改行を追加します。
この2つの改行が続くため、表示結果に空行が入ったように見えます。
末尾の改行文字をナル文字へ置き換えてから表示すれば、文字列に含まれていた改行を取り除けます。putsが追加する改行だけが残るため、空行が入りにくくなります。
fgetsで読み込んだ改行を取り除く方法
fgetsで読み込んだ改行が不要な場合は、文字列の末尾を調べて削除できます。
文字列の長さを調べるにはstrlenを使います。strlenを使うため、string.hをインクルードします。
#include <string.h>改行を取り除く処理は次のように書けます。
size_t len = strlen(message);
if (len > 0 && message[len - 1] == '\n') {
message[len - 1] = '\0';
}size_t にする理由は、strlen() の戻り値の型が size_t だからです。
size_t は、オブジェクトの大きさや配列の要素数を表すために用意された符号なし整数型です。
改行を取り除く処理の流れ
この処理は、次の順番で動きます。
| 順番 | 処理内容 |
|---|---|
| 1 | strlenで文字列の長さを求める |
| 2 | 文字列の長さが1以上か確認する |
| 3 | 最後の文字が改行文字か確認する |
| 4 | 改行文字をナル文字へ置き換える |
例えば、messageが次の内容だったとします。
'B' 'o' 'o' 'k' '\n' '\0'strlenが返す長さは5です。最後の文字はmessage[4]なので、message[len-1]で調べられます。
最後の改行文字をナル文字へ置き換えると、次のようになります。
'B' 'o' 'o' 'k' '\0'この変更によって、文字列はBookの直後で終わります。
lenが0より大きいことを確認する理由
次の条件では、最初にlenが0より大きいことを確認しています。
if (len > 0 && message[len - 1] == '\n') {文字列の長さが0の場合、len-1は文字列の有効な添字になりません。
そのため、最後の文字を調べる前に、少なくとも1文字あることを確認します。
論理AND演算子&&には、左側が偽の場合に右側を評価しない性質があります。lenが0の場合はmessage[len-1]を調べないため、不正な位置を参照することを防げます。
改行文字が入らない場合もある
fgetsを使っても、必ず改行文字が配列に格納されるとは限りません。
次のような場合は、末尾に改行文字がないことがあります。
- 配列がいっぱいになり、改行文字へ到達する前に読み込みが終わった
- 改行文字を読み取る前にEOFへ到達した
- 入力元の最後の行が改行文字で終わっていない
そのため、最後の文字を無条件にナル文字へ置き換えてはいけません。
次のように、最後の文字が本当に改行文字であることを確認してから置き換えます。
if (len > 0 && message[len - 1] == '\n') {
message[len - 1] = '\0';
}改行文字がない場合は、文字列を変更せずにそのまま残します。
文字列の入力と出力を繰り返すプログラム
fgetsをwhile文と組み合わせると、EOFへ到達するまで1行ずつ文字列を読み込めます。
次のプログラムでは、読み込んだ文字列の末尾から改行を取り除き、案内文と一緒に表示します。
EOFまで入力したメモを繰り返し表示するプログラム
ファイル名:12_4_2.c
#include <stdio.h>
#include <string.h>
int main(void)
{
char note[100];
puts("メモを1行ずつ入力してください。");
puts("入力を終了するにはEOFを送ります。");
/* EOFまで1行ずつ読み込む */
while (fgets(note, sizeof(note), stdin) != NULL) {
size_t len = strlen(note);
/* 末尾の改行文字を取り除く */
if (len > 0 && note[len - 1] == '\n') {
note[len - 1] = '\0';
}
printf("受け取ったメモ: %s\n", note);
}
puts("入力を終了しました。");
return 0;
}実行結果の例
次の3行を入力した場合の例です。
メモを1行ずつ入力してください。
入力を終了するにはEOFを送ります。
配列の復習をする
受け取ったメモ: 配列の復習をする
fgetsの戻り値を確認する
受け取ったメモ: fgetsの戻り値を確認する
改行文字の扱いを覚える
受け取ったメモ: 改行文字の扱いを覚える
入力を終了しました。入力した内容は端末のエコーバックによって表示され、その後にプログラムが受け取ったメモを表示します。
繰り返し入力プログラムの解説
必要なヘッダをインクルードする部分
#include <stdio.h>
#include <string.h>stdio.hは、fgets、puts、printf、stdinを使うためにインクルードしています。
string.hは、文字列の長さを求めるstrlenを使うためにインクルードしています。
文字列を格納する配列
char note[100];入力した1行を格納するために、100要素のchar型配列noteを用意しています。
fgetsは最大99文字までを読み込み、最後にナル文字を付けます。
入力方法を案内する部分
puts("メモを1行ずつ入力してください。");
puts("入力を終了するにはEOFを送ります。");2回のputsで、入力内容と終了方法を案内しています。
putsは文字列の最後に改行を追加するため、それぞれの案内が別の行に表示されます。
fgetsをwhile文の条件式で使う部分
while (fgets(note, sizeof(note), stdin) != NULL) {fgetsで1行を読み取り、その戻り値がNULLではない間、while文を繰り返します。
処理の流れは次のとおりです。
| 手順 | 処理内容 |
|---|---|
| 1 | fgetsで標準入力から1行を読み込む |
| 2 | 読み込んだ文字列をnoteへ格納する |
| 3 | fgetsの戻り値がNULLではないか確認する |
| 4 | 読み込みに成功していればwhile文の中を実行する |
| 5 | 次の繰り返しで新しい1行を読み込む |
| 6 | NULLが返されたらwhile文を終了する |
読み込みと成功判定を1つの条件式で行っています。
この形は、標準入力だけでなく、ファイルから1行ずつ読み込む場合にも応用できます。
文字列の長さを取得する部分
size_t len = strlen(note);strlenでnoteに格納されている文字列の長さを調べ、その結果をsize_t型のlenへ代入しています。
strlenが返す長さには、末尾のナル文字は含まれません。改行文字が文字列に含まれている場合、その改行文字は長さに含まれます。
改行文字を取り除く部分
if (len > 0 && note[len - 1] == '\n') {
note[len - 1] = '\0';
}文字列の長さが1以上であり、最後の文字が改行文字である場合、その位置をナル文字へ変更します。
この処理によって、fgetsが読み込んだ改行文字を文字列から取り除けます。
入力内容を表示する部分
printf("受け取ったメモ: %s\n", note);printfの%s変換指定を使って、noteに格納されている文字列を表示しています。
改行文字はすでに取り除かれているため、書式文字列の最後にある\nによって1回だけ改行されます。
while文を終了する条件
fgetsがNULLを返すと、while文の条件が偽になり、繰り返しを終了します。
NULLが返される主な理由は次のとおりです。
- 1文字も読み込む前にEOFへ到達した
- 入力エラーが発生した
このプログラムでは、EOFと入力エラーを区別せず、どちらの場合も繰り返しを終了します。
入力終了を表示する部分
puts("入力を終了しました。");while文を抜けた後、入力処理が終わったことを表示します。
EOFの入力方法
繰り返し入力を終了するには、標準入力へEOFを伝えます。
| 実行環境 | 一般的なEOFの入力方法 |
|---|---|
| Windows | Ctrl+Zを押した後にEnter |
| UNIXまたはLinux | Ctrl+D |
Windowsでは、一般的に行の先頭でCtrl+Zを押し、その後にEnterを押します。
UNIXやLinuxでは、入力がない状態でCtrl+Dを押します。同じ行にまだプログラムへ渡されていない文字がある場合、最初のCtrl+Dではその文字がプログラムへ渡されます。空の入力状態でもう一度Ctrl+Dを押すと、EOFとして扱われます。
長い入力では1行が分かれることに注意しよう
fgetsは、指定した配列に入る範囲だけを読み込みます。
入力した1行が配列へ収まらない場合、残りの文字は標準入力に残ります。そのため、次のfgetsが残りの部分を新しい入力として読み取ります。
例えば、配列の大きさが10の場合、入力から読み取れるのは最大9文字です。20文字の行を入力すると、複数回のfgetsに分かれて読み込まれる可能性があります。
| 状況 | 結果 |
|---|---|
| 改行まで配列に収まる | 1回のfgetsで1行を読み込める |
| 改行まで配列に収まらない | 残りが標準入力に残る |
| 次にfgetsを呼び出す | 残っている文字から読み込みを再開する |
fgetsは配列の範囲を超えて書き込みませんが、どのような長さの入力を想定するかを考えて、十分な大きさの配列を用意する必要があります。
fgetsとputsから学べること
fgetsとputsを学ぶと、単に文字列を入出力する方法だけでなく、C言語の文字列に関するさまざまな基本が見えてきます。
| 学べること | 内容 |
|---|---|
| 文字列入力 | char型配列へ1行を読み込む方法が分かる |
| 読み込み上限 | 配列の大きさに合わせて読み込む考え方が分かる |
| ナル文字 | 文字列の終わりを表す仕組みが分かる |
| 改行文字 | Enterによる改行が配列へ入ることを理解できる |
| 戻り値の判定 | NULLによって読み込み結果を確認できる |
| 文字列出力 | putsで文字列を1行表示できる |
| 繰り返し入力 | while文とfgetsを組み合わせる方法が分かる |
| EOF | 入力の終わりを使って繰り返しを終了できる |
fgetsとputsはシンプルな関数ですが、配列、ポインタ、改行、ナル文字、EOF、NULLなど、今後の文字列処理やファイル入出力につながる大切な要素を含んでいます。
fgetsとputsを使うときの確認事項
fgetsとputsを使うときは、次の点を確認しましょう。
- stdio.hをインクルードしているか
- 読み込み先としてchar型の配列を用意しているか
- 第2引数に配列の大きさに合った値を指定しているか
- 標準入力では第3引数にstdinを指定しているか
- fgetsの戻り値がNULLではないか確認しているか
- 入力した改行文字が配列に含まれていないか
- putsが自動的に改行を追加することを理解しているか
- 不要な改行は、最後の文字を確認してから取り除いているか
- 入力が配列へ収まらない場合を考えているか
- EOFによって入力が終了する場合を考えているか
文字列入力では、読み込めたように見えることだけで判断せず、戻り値、配列の大きさ、改行文字を確認することが大切です。
fgetsで入力範囲を指定し、戻り値を確認しながら文字列を受け取り、目的に応じてputsやprintfで表示する流れに慣れていきましょう。
