たのしい日棄帳

毎日更新(遅刻あり)ゆるゆる生活ログ

日記 #54

まえがき

書くことも無いし細かいメモを残す

活動ログ

sscanfのフォーマット指定子で入力を読み飛ばす

後から見直したら何言ってるか分かりにくかったのでメモを残しておく。
単にフォーマット指定子の扱い方をド忘れしていただけなので大丈夫(?)

何がしたいのか

C/C++で書かれたコード中のsscanf関数で指定したフォーマット指定子のうち、
不要な入力部分に対する格納先アドレスの記述を省略したい。

#include <cstdio>

int func() {
    // 省略

    int n;
    char str[100];
    char dump[20];
    
    sscanf(str, "%[^0-9]%d", dump, &n);

    // 省略
}

文字列のうち、何が来るか分からない英字や記号で構成される部分を1つ目の指定子で受けて、
2つ目で目当ての数値を受け取るつもりらしい。色々突っ込みたい点はある。
数値は負数や0パディングは考えなくていいのでこれで十分だったはず。
strに入る文字数やnがintの範囲なのも保証されている。

3番目の引数dumpが単なるプレースホルダ―として使われていていっそ無くしてしまいたい。
ワケあって、元のコードを大きく変えるようなことは避けたい(重要)

答え

    sscanf(str, "%*[^0-9]%d",  &n);

不要な部分にマッチする指定子の%と修飾子の間に*を付ける。
指定子の数とアドレス変数の個数の不一致についてのコンパイルエラーは出ない。

参考

renoji.com

% の直後に * を指定すると、そのデータは、変数に格納されずに読み飛ばされる。この場合、対応するアドレスを scanf などの引数に渡す必要はない。

www.cplusplus.com

An optional starting asterisk indicates that the data is to be read from the stream but ignored (i.e. it is not stored in the location pointed by an argument).

日本語でそれっぽいワードでググってもいまいち見つからないな
…と思って"c format specifier asterisk"とかで調べたらすぐ見つかった。ググり方が悪かった反省。

運動

  • 歩数:0
    • 今日も雨

食事

  • 朝食:赤いきつねペプシゼロ、紅茶と水
  • 昼食:くるみパン3つ、紅茶
  • 夕食:かぼちゃの煮物、緑茶

睡眠

  • 2時までに寝る予定

他、ルーチン

  • ※ラジオ土日分は聞かないので無し
  • 読書

あとがき

散歩にでも出かけたかった。天気は相変わらず安定しない。