トップC-Tips > printf関数の使い方

printf関数の使い方

printf関数のほんの少しだけ珍しい使い方を紹介しょう。

1.符号付き整数の出力と入力

printf関数の書式指定としては、%f(浮動小数点), %d(整数),%c(文字),%s(文字列)などが 主に使われるが、少し珍しい使い方もできる。

C言語コンパイラやインタプリタの開発で、下のような書式の文字列を生成したり、 このような文字列から、+2 とか -3 を読みとる必要が生じた。

mov eax,[ebp+2]
lea eax,[ebp-3]

次のよう %+d とすれば、符号付きで出力される。 disp の値が -3 のときは [ebp-3] 、2 のときは [ebp+2] と出力される。

sprintf(buf, "mov eax,[ebp%+d]", disp);

一方、正負の値をとる数値を読みとるには次のようにする。

sscanf(buf, "mov eax,[ebp%d]", &disp);

[ebp+2]のときは、dispの値は 2 となり、 [ebp-3] ならば、dispの値は -3 となる。

2.部分文字列のコピー[2012.11.10]

下のプログラムでは、"1234abcd"中の部分文字列 "4abc" が buf にコピーされる。

    char *str = "1234abcd";
    char buf[10];
    sprintf(buf, "%.4s", str+3);

.4 は4バイト幅を表す。 部分文字列のコピーは次のように、strncpy関数を使って実現することができる。 この方が実行時間は短い。 strncpy関数では、文字列末尾を表す '\0' がコピーされないため、 このための代入文が必要となる。

    char *str = "1234abcd";
    char buf[10];
    strncpy(buf, str+3, 4);
    buf[4] = '\0';

切り出す文字列の幅が固定ではなく、値が変わる場合、書式指定を "%.*s" として、 幅を次の引数とすればよい。 すなわち、 sprintf(buf, "%.*s", 4, str+3); は sprintf(buf, "%.4s", str+3); を意味する。 プログラム例を下に示す。

#include <stdio.h>

int main() {
    char *str = "1234abcd";
    char buf[10];

    sprintf(buf, "%.*s", 4, str+3);
    printf("'%s'\n", buf);
}

実行結果は次の通りである。

c:\mh\www\c-tips\io>printf01
'4abc'

このような部分文字列のコピーが1、2箇所で済むならば、sprintf関数を使わず、 strncpy関数を使う方が無難である。 しかし、プログラム中に部分文字列のコピーが数多く現れる場合など、 sprintf関数による部分文字列のコピーが有効なケースがある。