【C言語入門】scanfで数値、文字列の入力(sscanfの使い方も解説)

scanfって使ってますか?C言語ではscanfを使ってキーボードで値を入力することができます。入力した値は基本的には文字列として扱われます。

でも、書式を設定することで数値として変換して使用することもできるので便利です。

この記事では、文字列の入力と変換について

  • scanfの使い方について

という基本的な内容から、

  • scanfを使う上での注意点
  • sscanfの使い方について
  • scanf_sについて

など応用的な使い方の内容についても解説していきます。

今回は文字列の入力と変換について、使い方をわかりやすく解説します!

scanfの使い方について

scanf関数を使うとキーボードから書式付きで入力することができます。

scanf関数の第1引数には出力する書式を指定し、第2引数以降には入力する変数のアドレスを記入します。

第2引数以降は可変長引数で必要に応じて指定することができます。

第1引数の書式文字列は変換指定子を使って指定します。まずは変換指定子について説明していきます。

なお、アドレスについてはこちらのサイトで詳しく解説していますので、ぜひ参考にしてください。

【C言語入門】ポインタのわかりやすい使い方(配列、関数、構造体)
更新日 : 2019年4月23日

変換指定子とは(dobule型で入力)

入力する文字列の変数の型を指定するために、変換指定子という記号を使用します。変数の型の種類によって使用する変換指定子は変わってきます

主な変換指定子とそれに対応する変数の型は次の通りです。

%指定子対応する型説明
%cchar文字
%schar *文字列
%dint, short10進の整数
%ffloat浮動小数点数
%lfdouble倍精度浮動小数点数

ここではdouble型の数値を入力する場合について、サンプルコードで確認しましょう。

実行結果:

このサンプルコードでは、キーボード入力した文字列を変換指定子「%lf」を使ってdouble型に変換して、変数dに格納しています。

変換指定子について、こちらのサイトで詳しく解説していますので、ぜひ参考にしてください。

【C言語入門】printfで文字列を表示(sprintfの使い方も解説)
更新日 : 2019年5月6日

数値を入力する場合

scanf関数で入力した値は基本的には文字列として扱われます。

しかし、scanf関数の第1引数の書式文字列で数値型の変換指定子を指定すると、数値として変数に格納することができます。数値として変数に格納されますので、算術演算子を使って計算をすることも可能です。

サンプルコードで確認しましょう。

実行結果:

このサンプルコードでは、キーボード入力した文字列を変換指定子「%lf」を使ってdouble型に変換して、変数dに格納しています。

その後、変数dに1.0を加算した値を出力表示しています。

文字列を入力する場合

scanf関数を使って文字列を入力する場合について、サンプルコードで確認しましょう。

実行結果:

このサンプルコードでは、キーボード入力した文字列を変換指定子「%s」を使って文字列型に変換して、変数strに格納しています。

複数入力する方法

複数入力する場合は、scanf関数の第1引数の書式文字列で指定します。

入力する値の間にスペース(空白文字)を区切り文字とする場合について、サンプルコードで確認しましょう。

実行結果:

このサンプルコードでは、キーボード入力の書式を空白文字で区切られた文字列2つで指定しています。

キーボード入力後に空白文字で区切られた文字列はそれぞれ「str1」、「str2」のアドレスに値に格納され、printf関数を使って出力表示されています。

配列を入力する場合

文字列以外の配列に値を入力する場合について、サンプルコードで確認しましょう。

実行結果:

このサンプルコードでは、空白文字で区切られた文字列3つをキーボードで入力しています。

キーボード入力後に空白文字で区切られた文字列はそれぞれ「num[0]」、「num[1]」、「num[2]」のアドレスに値に変換後格納され、printf関数を使って出力表示されています。

なお、配列の使い方についてはこちらのサイトで詳しく解説していますので、ぜひ参考にしてください。

【C言語入門】配列の使い方まとめ(初期化、代入、宣言、コピー)
更新日 : 2019年4月22日

scanfを使う上での注意点

scanf関数は使う上でいくつか注意点があります。

改行文字の取り扱いについて

キーボードから入力された文字はバッファと呼ばれるメモリ領域にいったん読み込まれます。Enterキーが入力されるとバッファをクリアし、再びバッファが行える状態になります。

scanf関数では最後の改行文字はバッファの中に残ります。

したがって1番目の入力のあとに2番目に文字を1文字入力する場合などは、バッファの中に残った改行文字列を入力した文字として間違って処理しますので注意が必要です。

実際にサンプルコードで確認しましょう。

実行結果:

このサンプルコードでは1番目に文字列を入力し、2番目に1文字入力し、3番目に文字列を入力するように記述しています。

1番目にHelloと入力しEnterキーを押すと改行文字列を入力した文字として処理し、改行した空の1行を出力する処理が行われます。その後に2番目の&と1文字を入力しても、3番目の文字列を入力した処理が行われ表示されています。

したがって3番目の文字列の入力は実行できずに意図した処理ができていません。

これを改善するためには、下記のように「%*c」句を「%c」変換子の前に記述します。

「%*c」句で改行文字を除去します。

改善前:

改善後:

実行結果:

改善後の実行結果を確認すると改善前の改行文字による空の1行が出力されることはなく、意図通りに処理されています。

空白、タブの読み飛ばしについて

英文のように単語ごとに空白で区切って入力する場合も注意が必要です。

空白やタブが入力の中に含まれると、空白やタブの前までしかバッファーに読み取られません。サンプルコードで確認しましょう。

実行結果:

このサンプルコードでは、「Hello World!」とキーボード入力していますが、バッファーの内容を出力表示しても「Hello」とのみ表示されています。

空白以降はバッファーに読み取られていないことがわかります。

バッファーのオーバーランについて

バッファーのオーバーランとはメモリ上に確保した領域よりも大きなデータが渡されているのに、それを見逃して領域からあふれることをいいます。

あふれたデータがバッファに残って後で不具合を起こす可能性もあるので注意が必要です。サンプルコードで確認しましょう。

実行結果:

このサンプルコードでは4文字分のバッファーの確保に対して、いずれも4文字以上をキーボードから入力しています。

しかしscanf関数を使って入力データを格納し、printf関数を使って出力した結果を確認すると確保したバッファー以上のデータが表示されています。

これはC言語ではNULL文字(\0)が見つかるまで文字を出力し続けるようになっているためです。確保したメモリからあふれたデータが不具合を起こす可能性がありますので、注意が必要です。

入力異常の対処について

入力する際に意図した型と異なるデータを入力すると、意図した処理が行われないので注意が必要です。

サンプルコードで確認しましょう。

実行結果:

このサンプルコードでは、int型のデータのキーボード入力に対応していますが、「Hello」と文字配列を入力しています。

したがって、出力表示は意図しない結果となっています。

sscanfの使い方について

文字列を入力し変換する方法としてほかにもsscanf関数があります。

scanf関数ではコマンドラインでのキーボード入力に対して、sscanf関数ではファイルからの入力もしくはソースコードでの文字列の代入になります。

sscanf関数は第1引数に文字列のアドレスを、第2引数には入力文字列の書式を、第3引数以降には入力文字列から取り出す変数のアドレスを入力します。

サンプルコードで確認しましょう。

それではサンプルコードで確認しましょう。

実行結果:

このサンプルコードでは文字配列「str」に文字列を入力しています。

これをsscanf関数の第1引数に代入し、第2引数の書式に従い、第3引数以降で2つの文字列のアドレスを指定しています。文字列の入力から得られた結果をprintf関数を使って出力表示しています。

scanf_sについて

Visual StudioのC++の環境でコンパイルする際には注意が必要です。

VisualC++ではscanf関数を使用するとコンパイルエラーが発生し、scanf_s関数を使うようにメッセージが表示される場合があります。

scanf_s関数を使う場合は、文字列で受け取る領域のサイズを指定する必要があります。

なお、書式文字列に%dを使って整数値を入力する場合などはサイズが決まっているので、サイズを指定する必要はありません。

サンプルコードで確認しましょう。

実行結果:
scanf01

まとめ

ここでは、文字列の入力と変換について説明しました。

キーボード入力の場合に使われるscanf関数と文字列入力の場合に使われるsscanf関数の使い方について確認してきました。

データの型や入力文字列の書式、文字数が意図したものと異なる場合などは注意が必要です。使いこなすことができるように、この記事を何度も参考にして下さいね!

LINEで送る
Pocket

最短でエンジニアを目指すなら侍エンジニア塾

cta_under_bnr

侍エンジニア塾は業界で初めてマンツーマンレッスンを始めたプログラミングスクールです。これまでの指導実績は16,000名を超え、未経験から数多くのエンジニアを輩出しています。

あなたの目的に合わせてカリキュラムを作成し、現役エンジニア講師が専属であなたの学習をサポートするため効率よく学習を進めることができますよ。

無理な勧誘などは一切ありません。まずは無料体験レッスンを受講ください。

無料体験レッスンの詳細はこちら

書いた人

長野 透

長野 透

熊本在住のフリープログラマ兼ライターです。C/C++/C#、Java、Python、HTML/CSS、PHPを使ってプログラミングをしています。専門は画像処理で最近は機械学習、ディープラーニングにはまっています。幅広くやってきた経験を活かしてポイントをわかりやすくお伝えしようと思います。
お問合せはこちらでも受け付けています。
[email protected]

おすすめコンテンツ

あなたにぴったりなプログラミング学習プランを無料で診断!

プログラミング学習の効率を劇的に上げる学習メソッドを解説