このようなコードを使用してテーブルを印刷します
print "\t1%s\t2%s\t3%s\t4%s", str1, str2, str3, str4
しかし、いくつかの str 幅が少し長いと、このように出力されます
1blabla 2blabla 3blabla 4blabla
1blablablabla 2blabla 3blabla 4blabla
これらの文字列をフォーマットするより良い方法はありますか?
まず、列ごとに、各要素を表示するのに必要な最大長を決定します。たとえば、列エントリを反復処理して最大長を見つけますstrlen()
。次に、行ごとに、対応する列エントリを出力し、必要に応じてスペースを埋めます。
これは、文字列へのポインターの 2D 配列を取る C のプリティ プリンターです (ここで、各「行」はNULL
終了し、最後の行はすべてNULL
s で構成されます)。
void print_pretty(char ***arr)
{
int i, j, cols;
/* count columns */
j = cols = 0;
while (arr[0][j++]) cols++;
/* init column sizes */
size_t sizes[cols];
for (j = 0; j < cols; sizes[j++]=0);
/* 1st pass: calculate column widths */
for (i = 0; arr[i][0]; i++)
for (j = 0; arr[i][j]; j++)
if (strlen(arr[i][j]) > sizes[j])
sizes[j] = strlen(arr[i][j]);
/* 2nd pass: print table */
for (i = 0; arr[i][0]; i++) {
for (j = 0; arr[i][j]; j++)
printf("%-*2$s ", arr[i][j], sizes[j]);
puts("");
}
}
最も醜い部分は、C99 可変サイズ配列と への呼び出しの書式指定子printf()
です。また、1 つ最適化することもできますstrlen()
。
出力は次のようになります。
foo bar baz
snafu fubar x
コンパイル時の文字列の最大長がわかっている場合は、printf()
フォーマット指定子を使用してその長さを簡単に指定できます。
printf("%12s %12s %12s %12s\n", str1, str2, str3, str4);
または、C++ストリームマニピュレーターを使用します。
#include <iomanip>
...
cout << setw(12) << str1 << ... << '\n';
これにより、可変幅の列が必要な場合は、実行時に列幅を渡すこともできます。printf()
フォーマット指定子を変更し、文字列の前に長さを渡すことによって、これを行うこともできます。
printf("%*s ...\n", str1.length(), str1, ...);
stdio
C ++でコードとコードを混在させるのはスタイルが悪いと考えられてiostream
いますが、コードが読みにくく冗長にならない限り、一般的には後者の方が適しています。