web-dev-qa-db-ja.com

Cでこのような数値を整列するにはどうすればよいですか?

この例のように、Cの一連の数値をprintf()に揃える必要があります。

-------1
-------5
------50
-----100
----1000

もちろん、それらの間には数字がありますが、手元の問題には関係ありません...ああ、ダッシュをスペースと考えてください。ダッシュを使用したので、何が欲しいのか理解しやすくなりました。

私はこれしかできません:

----1---
----5---
----50--
----100-
----1000

またはこれ:

---1
---5
--50
-100
1000

しかし、これは私が望むものではなく、printf()のみを使用して最初の例に表示されるものを達成することはできません。まったく可能ですか?

編集:
申し訳ありませんが、私は急いでいて、自分自身をうまく説明しませんでした...私の最後の例とすべての提案(「%8d」のようなものを使用する)は機能しません。 1000でも、必ずしも1000または100または10に達するとは限りません。

表示する桁数に関係なく、最大の数字には最大で4つの先行スペースのみが必要です。 1〜1000(A)と1〜100(B)の数字を表示する必要があり、両方に「%4d」を使用するとします。これは出力になります。

A:

---1
....
1000

これは私が欲しい出力です...

B:

---1
....
-100

これは私が望む出力ではありません、私は実際にこれが欲しいです:

--1
...
100

しかし、私が言ったように、私は印刷しなければならない数字の正確な数を知りません、それは1桁、2、3またはそれ以上を持つことができ、関数はすべてのために準備されるべきです。そして、さらに4つの追加の先行スペースが必要ですが、それはそれほど重要ではありません。

編集2:欲しいもの、必要な方法、それは不可能なようです(David ThornleyとBlank Xavierの回答と私のコメントを確認してください)。お時間をありがとうございました。

31
Ricardo Amaral

これを私の便利なHarbison&Steeleで調べてください。

フィールドの最大幅を決定します。

int max_width, value_to_print;
max_width = 8;
value_to_print = 1000;
printf("%*d\n", max_width, value_to_print);

Max_widthはint型である必要があり、アスタリスクを使用する必要があることに注意してください。アスタリスクは、必要なスペースに基づいて計算する必要があります。あなたのケースでは、最大数の最大幅を計算し、4を追加する必要があります。

45
David Thornley

なぜprintf("%8d\n", intval);が機能しないのですか?そうすべき...

「動作しない」例のフォーマット文字列を表示しなかったので、他に何を伝えるべきかわかりません。

#include <stdio.h>

int
main(void)
{
        int i;
        for (i = 1; i <= 10000; i*=10) {
                printf("[%8d]\n", i);
        }
        return (0);
}

$ ./printftest
[       1]
[      10]
[     100]
[    1000]
[   10000]

編集:質問の明確化に対する回答:

#include <math.h>
int maxval = 1000;
int width = round(1+log(maxval)/log(10));
...
printf("%*d\n", width, intval);

幅の計算では、対数10 + 1が計算され、桁数が得られます。ファンシー*を使用すると、フォーマット文字列の値に変数を使用できます。

実行の最大値を知る必要がありますが、どの言語や鉛筆と紙でもそれを回避する方法はありません。

46
dwc
    printf("%8d\n",1);
    printf("%8d\n",10);
    printf("%8d\n",100);
    printf("%8d\n",1000);
3
Alex B

文字列に変換してから、フォーマット指定子として「%4.4s」を使用してください。これにより、固定幅形式になります。

1
MM

前もって幅がわからない場合、唯一可能な答えは、何らかの一時バッファで出力をステージングすることに依存します。小さなレポートの場合、データを収集し、入力が制限されるまで出力を延期するだけが最も簡単です。

大規模なレポートでは、収集されたデータが適切なメモリ境界を超える場合、中間ファイルが必要になる場合があります。

データを取得したら、各値のイディオムprintf("%*d", width, value)を使用して、データをレポートに後処理するのが簡単です。

あるいは、出力チャネルがランダムアクセスを許可する場合は、先に進み、(短い)デフォルトの幅を想定したレポートのドラフトを作成し、幅の想定に違反した場合はいつでも戻って編集できます。また、このフィールドの外側にあるレポート行に無害な方法でパディングできること、またはこれまでの出力をread-modify-writeプロセスで置き換えてドラフトファイルを破棄することを前提とします。

ただし、正しい幅を事前に予測できない場合、何らかの形式の2パスアルゴリズムを使用しないと、目的の処理を実行できません。

0
RBerteig

質問からわかる限り、必要なパディングの量は、持っているデータによって異なります。したがって、これに対する唯一の解決策は、印刷前にデータをスキャンし、最も広いデータを把握し、アスタリスク演算子を使用してprintfに渡すことができる幅の値を見つけることです。

loop over data - get correct padding, put into width

printf( "%*d\n", width, datum );
0
user82238

それでは、パディングとしてスペースを含む8文字幅のフィールドが必要ですか? 「%8d」をお試しください。 参照先

[〜#〜] edit [〜#〜]:あなたがしようとしているのは、printfだけで処理できるものではありません。あなたが書いている最長の数字が何であるかを知りません。 printfsを実行する前に最大数を計算し、フィールドの幅として使用する桁数を計算する必要があります。次に、snprintfなどを使用して、その場でprintf形式を作成できます。

char format[20];
snprintf(format, 19, "%%%dd\\n", max_length);
while (got_output) {
    printf(format, number);
    got_output = still_got_output();
}
0
mkb

編集された質問を見て、表示される最大数の桁数を見つけてから、printf()を使用して、または_%*d_を使用してsprintf()形式を生成する必要があります。 _*_のintとして渡される桁数と、その後の値。最大数を取得したら(事前に決定する必要があります)、「整数対数」アルゴリズムで桁数を決定できます(ゼロになるまでに10で除算できる回数)。またはsnprintf()を使用して、バッファーの長さをゼロ、フォーマットを_%d_、文字列をnullにします。戻り値は、フォーマットされた文字数を示します。

出現前に最大数がわからず、決定できない場合、あなたはスヌークされます-あなたができることは何もありません。

0
#include<stdio.h>
int main()
{
 int i,j,n,b;
 printf("Enter no of rows ");
 scanf("%d",&n);
 b=n;
 for(i=1;i<=n;++i)
 {
    for(j=1;j<=i;j++)
    {
        printf("%*d",b,j);
        b=1;
    }
        b=n;
    b=b-i;
    printf("\n");


 }
 return 0;
}
0
vino