Cで新しいフォーマット指定子を書くことは可能ですか? たとえば、 %g は、同等の符号なし整数から IP アドレスを ABCD 形式で出力する形式指定子であるとしましょう。
int ip_addr = Some integer
printf("ip address = %g", ip_addr);
出力: IP アドレスを ABCD 形式で出力します
printf 関数 (より正確にはその形式解析関数) を再実装する必要があります。あなたができることは、ipアドレスをサポートする関数内にprintfをラップするか、これを行うことです:
#define FMT_IP "%d.%d.%d.%d"
#define FMT_IP_ARG(ip) getA(ip), getB(ip), getC(ip), getD(ip)
getX 関数またはマクロは、IP アドレスを表す特定の整数の X 部分を取得します。
それで:
printf("ip address = " FMT_IP "\n", FMT_IP_ARG(ip));
@chux's answerに行きます。これは、必要な一時バッファーの大きさを知ることができれば、シンプルで移植可能です。
ただし、GNU ライブラリ (glibc) を使用している場合は、printf
新しい指定子で拡張できます。ほとんどすべての小文字のフォーマット コードが使用されており、残りは将来の C/Posix 標準で使用される可能性があるため、大文字をフォーマット コードとして使用することを強くお勧めします。この機能は、glibc のマニュアルに記載されています。
GNU 機能に基づいて、同様のかなり互換性のある機能が BSD ライブラリ用に作成されました。どうやら Mac OS X で利用できるようですが、その事実を保証することはできません。xprintf(3)およびxprintf(5)のAppleオンラインマニュアルページで見つけました。
上記のリンク先のドキュメントに例があります。
printf()
新しい指定子を追加するには、新しい指定子を処理する独自の関数を書き直したり作成したり、printf()
それを呼び出したりする必要があります。これらのアプローチはどちらも困難です。
"%s"
別の方法は、文字列を形成する独自の関数を使用して作成することです。
C99 以降では、複合リテラルを使用して、必要なバッファー スペースを形成します。
#include <stdio.h>
#define MYIP_N 16
#define MYIP(ip) myip((char [MYIP_N]){""}, (ip))
char *myip(char *dest, int ip) {
snprintf(dest, MYIP_N, "%d.%d.%d.%d", (ip >> 24) & 255, (ip >> 16) & 255,
(ip >> 8) & 255, (ip >> 0) & 255);
return dest;
}
int main(void) {
int ip1 = 0x01020304;
int ip2 = 0x05060708;
printf("%s %s\n", MYIP(ip1), MYIP(ip2));
return 0;
}
出力
1.2.3.4 5.6.7.8
これは、printf()
またはfprintf()
、sprintf()
、でも機能しますputs()
puts(MYIP(ip1));
1.2.3.4
標準ライブラリ関数を変更することはできませんが、 を受け入れ%g
て順番に呼び出すラッパー関数を作成することはできますprintf
。