4

Cで新しいフォーマット指定子を書くことは可能ですか? たとえば、 %g は、同等の符号なし整数から IP アドレスを ABCD 形式で出力する形式指定子であるとしましょう。

int ip_addr = Some integer

printf("ip address = %g", ip_addr);

出力: IP アドレスを ABCD 形式で出力します

4

4 に答える 4

6

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));
于 2016-01-06T17:01:29.000 に答える
2

@chux's answerに行きます。これは、必要な一時バッファーの大きさを知ることができれば、シンプルで移植可能です。

ただし、GNU ライブラリ (glibc) を使用している場合は、printf新しい指定子で拡張できます。ほとんどすべての小文字のフォーマット コードが使用されており、残りは将来の C/Posix 標準で使用される可能性があるため、大文字をフォーマット コードとして使用することを強くお勧めします。この機能は、glibc のマニュアルに記載されています。

GNU 機能に基づいて、同様のかなり互換性のある機能が BSD ライブラリ用に作成されました。どうやら Mac OS X で利用できるようですが、その事実を保証することはできません。xprintf(3)およびxprintf(5)のAppleオンラインマニュアルページで見つけました。

上記のリンク先のドキュメントに例があります。

于 2016-01-06T20:54:03.487 に答える
2

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
于 2016-01-06T17:29:17.187 に答える
0

標準ライブラリ関数を変更することはできませんが、 を受け入れ%gて順番に呼び出すラッパー関数を作成することはできますprintf

于 2016-01-06T17:00:30.317 に答える