scanf scanfの概要

scanf

出典: フリー百科事典『ウィキペディア(Wikipedia)』 (2021/11/23 00:15 UTC 版)

ナビゲーションに移動 検索に移動

標準入力(大抵はキーボード)からの入力を、書式に従って変数に読み込む機能を持つ。標準出力関数のprintfと対比させて考えると分かりやすい。

ユーザーからの入力を受ける、ごく基本的な機能を持つにもかかわらず、後述するように異常入力(エラー)に配慮すると相応の手間がかかるため、テストプログラムや入門書を除いてはあまり使われない。

このファミリーの関数には、入力ストリームを指定できる fscanf や、メモリ上の文字列ストリームを入力対象とする sscanf などがある。

形式

stdio.h内で以下の様に宣言されている。

int scanf(const char *format, ...);

printf と同様、第1引数のformatは、それに続く可変長の実引数の変換方法(書式)を指定する。また戻り値は入力(スキャン)に成功した入力項目の数が返される。

利用例を以下に示す。

#include <stdio.h>

int main(void)
{
  int x; /* スキャン結果を格納する変数。 */

  printf("x = ? "); /* 入力を促すプロンプト。 */
  /* スキャンと結果の確認。 */
  if (scanf("%d", &x) == 1) {
    printf("スキャン結果 = %d\n", x);
  }
  else {
    printf("スキャン失敗\n");
  }
  return 0;
}

変換指定

scanf の変換指定は次の形式をとる。

% [代入抑止][最大フィールド幅][長さ修飾子]変換指定子

代入抑止

フラグ 意味
* フォーマットに合わせて入力を読み込むが実引数に代入はされない。

例えば

char c;
scanf("%*c%c", &c);

というコードがあり、 "ab"という入力があった場合 1文字目の 'a' は無視され 2文字目の 'b' という文字が代入される。

長さ修飾子

修飾子 意味 導入バージョン
hh 実引数は char 型 C99以降
h 実引数は short 型 全バージョン
l(エル) 実引数は long 型または wchar_t 型または double 型 wchar_t についてはC95以降
ll(エルエル) 実引数は long long 型 C99以降
j 実引数は intmax_t 型 C99以降
z 実引数は size_t 型 C99以降
t 実引数は ptrdiff_t 型 C99以降
L 実引数は long double 型 全バージョン

変換指定子

指定子 意味 導入バージョン
d,i 10進符号付き整数 全バージョン
u 10進符号無し整数 全バージョン
o 8進符号無し整数 全バージョン
x,X 16進符号無し整数 全バージョン
e,E 浮動小数点数 全バージョン
f,F 浮動小数点数 全バージョン
g,G 浮動小数点数 全バージョン
a,A 浮動小数点数 C99以降
c 文字 全バージョン
s 文字列 全バージョン
p ポインタの値、対応する引数は void* になる。 全バージョン
n 整数変数に出力済み文字数を格納 全バージョン
% '%'の入力 全バージョン
[...] [ ]内で囲まれた文字だけを取得し、
それ以外の文字が現れた場所以降は入力を終了する(下記参照)。
全バージョン

[ ] は例えば

char str[256];
scanf("%[abc]", str);

というコードがあり、入力に "babaacdeabfghijabcef" という文字列が入った場合、str には "babaac" という文字列のみが入力され、残りの文字列は入力されずに終了する。strに代入されなかった、"deabfghijabcef"は入力ストリームに残る形となる。また[^ ... ]とした場合は逆に[ ]内の文字が入ってくるまで文字を読み込む。 例えば、

char str[256];
scanf("%[^abc]", str);

という場合、"ghetbceajk"と入力すると、str には"ghet"が代入される。上記と同様に、入力されなかった文字列は入力ストリームに保持される。

コード例

ソース:

#include <stdio.h>
#include <limits.h>

int main(void)
{
  int n1, n2, nadd, nsub, nmul, ndiv, nmod;

  printf("1つ目の入力数値:");
  if (scanf("%d", &n1) != 1) {
    puts("スキャン失敗");
    return -1;
  }
  printf("2つ目の入力数値:");
  if (scanf("%d", &n2) != 1) {
    puts("スキャン失敗");
    return -1;
  }
  if (n2 == 0) {
    /* ゼロ除算防止のチェック。 */
    puts("2つ目の数値は非ゼロを入力してください");
    return -1;
  }
  if (n1 == INT_MIN && n2 == -1) {
    /* 除算と剰余のオーバーフローエラー防止のチェック。 */
    puts("オーバーフローしない数値の組み合わせを入力してください");
    return -1;
  }

  nadd = n1 + n2;
  nsub = n1 - n2;
  nmul = n1 * n2;
  ndiv = n1 / n2;
  nmod = n1 % n2;

  printf("%d + %d = %d\n", n1, n2, nadd);
  printf("%d - %d = %d\n", n1, n2, nsub);
  printf("%d * %d = %d\n", n1, n2, nmul);
  printf("%d / %d = %d + %d / %d\n", n1, n2, ndiv, nmod, n2);

  return 0;
}

出力結果の例:

1つ目の入力数値:60
2つ目の入力数値:21
60 + 21 = 81
60 - 21 = 39
60 * 21 = 1260
60 / 21 = 2 + 18 / 21

  1. ^ [迷信] scanf ではバッファオーバーランを防げない” (日本語). C/C++迷信集. 株式会社きじねこ. 2010年2月28日閲覧。 “書式指定が不適切なために発生する脆弱性であって、scanf の問題ではありません。”


「scanf」の続きの解説一覧




固有名詞の分類


英和和英テキスト翻訳>> Weblio翻訳
英語⇒日本語日本語⇒英語
  

辞書ショートカット

すべての辞書の索引

「scanf」の関連用語

scanfのお隣キーワード
検索ランキング

   

英語⇒日本語
日本語⇒英語
   



scanfのページの著作権
Weblio 辞書 情報提供元は 参加元一覧 にて確認できます。

   
ウィキペディアウィキペディア
All text is available under the terms of the GNU Free Documentation License.
この記事は、ウィキペディアのscanf (改訂履歴)の記事を複製、再配布したものにあたり、GNU Free Documentation Licenseというライセンスの下で提供されています。 Weblio辞書に掲載されているウィキペディアの記事も、全てGNU Free Documentation Licenseの元に提供されております。

©2024 GRAS Group, Inc.RSS