chikuchikugonzalezの雑記帳

趣味とか日記とかメモとか(∩゚д゚)

printf/sprintfフォーマット指定子でフィールド幅を可変にする方法

まさかMUGEN関係の記事を見てて新たな知恵を得ようとは。それもC言語的な方面の。

発端はdrab氏 (でいいのかな) の%nの記事で、

4.フィールド幅、精度
 既に、メモリエディタさえ用意すれば%nを使えるようになったはずですが、ここでは%nを利用する上での小技を紹介します。printf()について勉強したなら%5dや%.5dなどの指定子も知っていると思います。前者はフィールド幅で、最低何桁表示するかを指定できます。後者は精度で、小数点以下何桁まで表示するかを指定できます。普通に数字を直接入力しても良いと思います。しかし、引数で指定した任意の値を入れることができる*を利用することで、ステコンの数を減らせたり、変数に格納した値を指定することができます。
 実際にL霊夢で使用しているもの例として示します。

text="%*d%n%d" ;59はF1、63はF5に対応
params = ifelse(gametime%2 = 1,63,59),1,4937032

制作日記 %nの説明

というのがDisplayToClipbardステコンでできるというものでした。まさかフィールド幅を動的に出来ようとはC言語自由すぎだろうと思わなくもない。
とりあえずMan page of PRINTFを参照してちょいと組んだのが次のプログラム。

#include <stdio.h>

int main(void) {
	int width = 30;
	int value = 20;

	printf("Test1 : %*d\n", width, value);
	printf("Test2 : %1$*2$d\n", value, width);

	return 0;
}

で結果。

~/Desktop>gcc -v
Using built-in specs.
COLLECT_GCC=gcc
COLLECT_LTO_WRAPPER=e:/programs/mingw/bin/../libexec/gcc/mingw32/4.5.2/lto-wrapp
er.exe
Target: mingw32
Configured with: ../../src/gcc-4.5.2/configure --build=mingw32 --enable-languages=c,c++,ada,fortran,objc,obj-c++ --enable-threads=win32 --enable-libgomp --enable-lto --enable-fully-dynamic-string --enable-libstdcxx-debug --enable-version-specific-runtime-libs --with-gnu-ld --disable-nls --disable-win32-registry --disable-symvers --disable-werror --prefix=/mingw32tdm --with-local-prefix=/mingw32tdm --enable-cxx-flags='-fno-function-sections -fno-data-sections' --with-pkgversion=tdm-1 --enable-sjlj-exceptions --with-bugurl=http://tdm-gcc.tdragon.net/bugs
Thread model: win32
gcc version 4.5.2 (tdm-1)

~/Desktop>gcc --std=c99 -o printf printf.c

~/Desktop>printf
Test1 :                             20
Test2 : %1$*2$d

~/Desktop>

"*m$"形式は使えませんでした(´・ω・`)