C言語関係掲示板

過去ログ

No.521.sscanfの使い方

[戻る] [ホームページ]
No.4081

sscanfの使い方
投稿者---市松(2002/12/27 02:25:07)


sscanfで文字列からデータを取得しているみたいなのですが、sscanfの使い方
を教えて下さい。

if (sscanf(buf+5, "%4s%*2c%2s%*2c%2s%*2c %2s%*2c%2s%*2c%2s",
date, date+4, date+6, date+8, date+10, date+12) != 6) continue;

found = sscanf(buf, "---- [%*[^[][%4s%*2c%2s%*2c%2s%*2c%2s%*2c%2s%*2c%2s",
date, date+4, date+6, date+8, date+10, date+12) == 6
&& strncmp(date, argv[1], len) == 0;

No.4085

Re:sscanfの使い方
投稿者---aki(2002/12/27 15:58:44)


ちょっと長くなりましたが必要なところだけを読んでください。

sscanf関数は第1引数が指す文字配列から得られる入力を変換し、第3引数以降
が指すオブジェクトに格納します。このとき、第2引数が指す文字列の指令に従
って変換を行います。

>sscanf(buf+5, "%4s%*2c%2s%*2c%2s%*2c %2s%*2c%2s%*2c%2s",
>                          date, date+4, date+6, date+8, date+10, date+12) 

この sscanf の第2引数の、

  "%4s%*2c%2s%*2c%2s%*2c %2s%*2c%2s%*2c%2s"

という文字列は以下のような12個の指令の並びです。

"%4s"
"%*2c"
"%2s"
"%*2c"
"%2s"
"%*2c"
" "
"%2s"
"%*2c"
"%2s"
"%*2c"
"%2s"

指令の意味は次の通りです。

"%4s"
  まず(もしあれば)空白類をスキップする。そこから次の空白類の文字の
  直前までの文字を対応する実引数が指す文字配列に格納する。ただし、
  読み込む文字の最大数を4文字に制限する。最後に格納した文字の後ろに
 はナル文字('\0')を付加する。

"%*2c"
 2文字を読み捨てる。代入は行わない。%s指令と違って、空白類文字はそ
  の他の文字と区別されない。ナル文字も付加しない。'*'は代入抑止を意
  味する。

"%2s"
  読み込む文字の最大数が2文字であることを除けば、"%4s"指令と同じ。

" "
  (もしあれば)空白類をスキップする。

例えば、配列 buf の内容が "XXXXX1995年10月27日 07時32分55秒" であれば、
date は "19951027073255"になります。

>sscanf(buf, "---- [%*[^[][%4s%*2c%2s%*2c%2s%*2c%2s%*2c%2s%*2c%2s",
>                          date, date+4, date+6, date+8, date+10, date+12)

こちらの sscanf の第2引数はこのような指令に分解されます。

"-"
"-"
"-"
"-"
" "
"["
"%*[^[]"
"["
"%4s"
"%*2c"
"%2s"
"%*2c"
"%2s"
"%*2c"
"%2s"
"%*2c"
"%2s"
"%*2c"
"%2s"

意味は次の通りです。

"-"
  1文字を読み取ってそれが'-'であるかどうかを調べる。もし'-'であれば
 それを単に読み捨てる。'-'でなければ次の指令を実行せずに sscanf から
  return する。

"["
  "-"と同じ。'-'が'['に変わるだけ。

"%*[^[]"
  '[' の直前までを読み捨てる。 %[] 指令は '[' と ']' の間に指定された文
 字が続く間だけ読み取りを続ける。例えば、%[abcde] は、'a','b','c','d',
 'e' のいずれかの文字が続く間読み取りを続け、それを対応する実引数が指す
 文字配列に格納する。%[] 指令の '[' の直後の '^' は「〜以外」を意味する。
 例えば %[^abcde]は 'a','b','c','d','e' 以外の文字が続く間読み取りを続
 け、それを対応する実引数が指す文字配列に格納する。'%' の直後の '*' は
 代入抑止を意味する。

例えば、配列 buf の内容が "---- [...[1995年10月27日 07時32分55秒]]" であ
れば、date は "19951027073255"になります。

sscanf関数は「代入した回数」を返却値とします。上の2つの sscanf はどちら
も成功すれば6を返します。でも "%s" 指令や "%c" 指令において、1文字も読み
取れなかった場合や "-"や"["のような照合指令が失敗した場合はそこで return
するので6より小さい値になります。


No.4086

たびたびですみません。
投稿者---市松(2002/12/27 16:29:51)


たびたびですみません。

下の方で、hatsuさんが質問されたことなのですが、
while (fscanf(stdin, " %255[^,],%d", buf, &val) == 2) {
についていも教えて下さい。

「" %255[^,],%d"」で、「"」と「%255」の間に半角スペースが入っているのは
どうしてなのですか。
ある場合とない場合で出力結果がことなるということなのですが。

お願いします。



No.4087

Re:たびたびですみません。
投稿者---aki(2002/12/27 16:53:46)


>「" %255[^,],%d"」で、「"」と「%255」の間に半角スペースが入っているのは
>どうしてなのですか。
>ある場合とない場合で出力結果がことなるということなのですが。

この半角スペースは「空白類文字(空白、改行、タブなど)を読み捨てよ」という指令です。