出力で同じ長さになるようにprintf()を使用して文字列をフォーマットする方法は?


92

私は2つの機能、のようなメッセージを生成する一つを有するStarting initialization...、別のどのチェックがコードおよび出力を返すを"Ok""Warning"または"Error"。ただし、生成される出力の長さは異なります。

Starting initialization...Ok.
Checking init scripts...Ok.

どのように私はこのようなものを得ることができます:

Starting initialization...       Ok.
Checking init scripts...         Ok.

回答:


159

たとえば、文字列フィールドの幅を指定できます

printf("%-20s", "initialization...");

そして、そのフィールドで印刷されるものはすべて、指定した幅になるように空白が埋め込まれます。

-そのフィールドにテキストを左寄せ。


130
悲しいかな、私はその高さを数えるほど賢くない。ただし、私の例から外挿するのに十分なほどインテリジェントであることが
質問者

3
正しい正当化はどうですか?K&Rで言及されているフラグはありません
Ungeheuer 2017年

9
デフォルトは右揃えです。がない-場合、データは指定した幅のフィールドで右揃えされます。
Carl Smotricz 2017

24

printf幅指定子を使用してフォーマットできます。例えば


printf( "%-30s %s\n", "Starting initialization...", "Ok." );

デフォルトでは右揃えを使用するため、左揃えを示すには負の幅指定子を使用します。


18

さらに、を選択する柔軟性が必要な場合widthは、次の2つの形式のいずれかを選択できます(切り捨てありまたはなし)。

int width = 30;
//no truncation uses %-*s
printf( "%-*s %s\n", width, "Starting initialization...", "Ok." );
// output is "Starting initialization...     Ok."

//truncated to the specified width uses %-.*s
printf( "%-.*s %s\n", width, "Starting initialization...", "Ok." ); 
// output is "Starting initialization... Ok."

13

%n特定の状況で役立つ修飾子もあります。これは、文字列がそれまで存在していた列を返します。例:テーブルのように、最初の行の幅内にある複数の行を書きたいとします。

int width1, width2;
int values[6][2];
printf("|%s%n|%s%n|\n", header1, &width1, header2, &width2);

for(i=0; i<6; i++)
   printf("|%*d|%*d|\n", width1, values[i][0], width2, values[i][1]);

どんな長さの同じ幅の2列の2つの文字列を出力しますheader1し、header2持っていることがあります。すべての実装%nがSolarisとLinuxにあるかどうかはわかりません。


このソリューションは機能しますが、これを取得してコードに配置する人は誰でも、メモリの脆弱性を導入するリスクに注意する必要があります
マシューコール

0

メッセージを整列させるために手動でスペースを追加して数えるというかなりローテクなソリューションもあります。メッセージ文字列に末尾のスペースを含めることを妨げるものはありません。


-2

\ t文字修飾子であるタブの使用から始めます。固定された場所(列、ターミナルの用語)に進みます。ただし、列幅(正しく思い出せば4文字)を超える違いがある場合は役に立ちません。

これを修正するには、固定数のタブ(5?6 ?、それを試す)を使用して "OK / NOK"を記述し、改行せずに(\ r)戻り、メッセージを記述します。


5
文字列がタブストップよりも長いため、結果として得られるタブとテキストの位置がずれる危険が常にあります。
PP。

そうではありません...最初にタブ付きのOK / NOKを書き込んでから、/ rでフレーズを書き込んでください。このフレーズは、OK / NOKを上書きする可能性があります。しかし、あなたのやり方はずっと良いです。私は否定的な正当化について知りませんでした。
jpinto3912 2009年
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.