scanf による文字列の入力
CoddyのCジャーニー「論理と制御フロー」セクションの一部。レッスン 14/63。
ヌル終端文字列の仕組みを理解したところで、次はユーザーから文字列を入力してもらう方法を学びましょう。scanf関数は%s書式指定子を使って文字列を読み取れますが、理解しておくべき重要な制限があります。
scanfで文字列を読み込むには、%s形式を使い、文字配列の名前を渡します(配列名はすでにアドレスなので、&演算子は付けません)。
char word[50];
printf("Enter a word: ");
scanf("%s", word);
printf("You entered: %s\n", word);ただし、scanf("%s", ...)には重大な制限があります。空白文字(スペース、タブ、改行)に遭遇すると、すぐに読み取りを停止します。つまり、ユーザーが「Hello World」と入力すると、scanfは「Hello」だけを取得し、「World」は入力バッファーに残します。
もう一つの重大な懸念は、scanfが入力が配列に収まるかどうかを確認しないことです。配列に収まりきらない長さの単語が入力されると、バッファオーバーフローが発生し、プログラムがクラッシュしたり、セキュリティ上の脆弱性が生じたりする可能性があります。想定される入力に対して、文字配列が十分な大きさであることを必ず確認してください。
こうした制限があるにもかかわらず、scanf("%s", ...)は単語を1つ読み取るのに最適です。次の課題では、まさにそれを練習します。
チャレンジ
簡単scanfを使ってユーザーから文字列入力を読み取り、それを表示するCプログラムを書きましょう。プログラムでは、次の処理を行います。
- ユーザーの入力を格納する、要素数30の
usernameという名前の文字配列を宣言する - もう一つの入力を格納する、要素数25の
hobbyという名前の文字配列を宣言する printfを使って、メッセージEnter your username:をユーザーに表示する%s書式指定子を使ってscanfでユーザー名を読み取り、username配列に格納するprintfを使って、メッセージEnter your hobby:をユーザーに表示する%s書式指定子を使ってscanfで趣味を読み取り、hobby配列に格納する- 以下に示す正確な形式で、
printfを使って両方の文字列を表示する
入力は、スペースを含まない単語2つとして、それぞれ別々に与えられます。
出力は、次の形式で結果を表示してください。
Enter your username:
Enter your hobby:
Hello [username], your hobby is [hobby]!たとえば、ユーザー名としてAlice、趣味としてreadingを入力した場合、出力は次のようになります。
Enter your username:
Enter your hobby:
Hello Alice, your hobby is reading!この課題では、scanfで%s書式指定子を使って文字列入力を読み取る方法、十分なサイズの文字配列を適切に宣言する方法、およびprintfを使ってユーザー入力を組み合わせて書式付き出力を行う方法の理解度を確認します。
自分で試してみよう
#include <stdio.h>
int main() {
// TODO: ここで文字配列を宣言する
// TODO: ここに入力を促して読み取るコードを書く
// TODO: 最終的な出力メッセージを表示する
return 0;
}このレッスンには短いクイズがあります。レッスンを始めて解答し、進捗を記録しましょう。
論理と制御フローのすべてのレッスン
自分で練習してみよう: Cオンラインコンパイラ