0

したがって、課題は、この出力を使用してプログラムを作成することです。

000042
420000
42
-42-

私の最初の試みは次のようなものでした:

int fortyTwo = 42;

cout << setfill('0') << setw(6) << fortyTwo << endl;
cout << fortyTwo << setfill('0') << setw(6) << endl;
cout << fortyTwo << endl;
cout << setfill('-') << setw(4) << fortyTwo << setfill('-') << endl;

これは私に次のようなものを与えました:

000042
42
000042
42-- (sometimes just -42)

著者の解決策は次のとおりです。

cout << setfill('0') << setw(6) << 42 << endl;
cout << left << setw(6) << 42 << endl;
cout << 42 << endl;
cout << setfill('-') << setw(4) << -42 << endl;

著者が setfill を 1 回しか使用しないのはなぜですか? setfill は最初の 2 行ではどのように機能しますが、3 行目で突然停止しますか? -42 の前に setfill('-') と setw(4) を配置すると、--42 ではなく -42- が生成されるのはなぜですか? 左揃え演算子は何に必要ですか?

最後に、私のバージョンが正しい出力を生成しないのはなぜですか?

4

3 に答える 3

0

setfill(ほとんどのostream修飾子と同様hexに、decleft、バイナリ 1、精度 IIRC など) 変更すると、その値が保持されます。

少しバックアップさせてください。

std::ostream(クラスcoutはのインスタンスです) には、内部書式設定値があります。フィラー文字が何であるか、16 進数で印刷するかどうかなどを伝える内部変数。

これらの値のほとんど (おそらく を除くすべてwidth) は、変更しない限り変更されません。したがって、一度設定するfillと、別のものに変更するまでそのままになります。

width違います(残念ながら:(彼らには理由があったと思います。)設定すると、次に書き込む項目だけが残り、その後0にリセットされます。

あなたが見逃しているように見える2番目のことは、widthandfillなどは何も出力せず、内部状態のみを変更するため、それらの後に来るものに適用されるということです。

それでは、ソリューションを分析しましょう。

fillを 0 に設定し、をwidth6 に設定し、42 を出力します。これは 2 文字であるため、4 つの 0 を追加して 6 に拡張します (デフォルトは右寄せのテキストであるため、左に)。これで何かが印刷されたので、widthリセットします(!)

ここで、新しい行 ( endl) を開始し、42 を出力し (ビット幅がリセットされるため、任意の幅で出力するだけで、塗りつぶす必要はありません!)、fillを 0 に設定します (既にfill変更されています! 変更するまでそのままです)。幅を 6 に設定し (ただし、既に印刷されている値ではなく、次の値のために!)、新しい行に進みます。

ここで、42 ( widthis 6 であるため、必要な 4 つの余分な文字を 0) で埋め (width印刷後にリセット)、新しい行に進みます。

塗りつぶしを - に設定し、幅を 4 に設定し、左側に 2 つ追加して 4 文字に拡張された 42 を印刷し (あなたが書いたのとは異なります... 奇妙なことに)、塗りつぶしを再び - (不要であり、その後は何も印刷しないため使用されません。setfill他のフォーマットは、その後に発生するものにのみ影響します!)

于 2013-07-19T01:53:05.200 に答える
0

setw() は次の出力にのみ影響します。他のすべての質問は、ほとんどこの動作の結果です。つまり、出力を広げようとしない限り、文字の埋め込みや位置合わせは行われません。

于 2013-07-19T01:41:56.957 に答える
0

std::setw次の出力フィールドの幅のみを決定しますが、渡されたストリーム オブジェクトの以降のすべてstd::setfillの印刷操作に使用される埋め込み文字を設定します。

したがって、実際には、出力の 3 行目で塗りつぶし文字が突然停止することはありません。ただし、std::setwその出力が生成される前にマニピュレータがないため、塗りつぶし文字は単純に使用されません。

std::left、のようstd::setfillに、キャンセルされるまで有効です。したがって、出力の 2 行目に設定された後、4 行目が生成されたときにも有効になります。4 行目は埋め込み文字がであるため-、この文字は行末に追加されます。(-先頭の は、出力文字列の一部として明示的に指定されているためです。)


参照用の標準 (C++11) からの引用。

  1. std::setfill27.7.4/5 で説明されています。

    unspecified setfill(char_type c);

    戻り値: out が basic_ostream 型のオブジェクトであり、 c が型を持つcharT場合、式out << setfill(c)は を呼び出したかのように動作するような未指定の型のオブジェクトf(out, c)。関数fは次のように定義されます。

    template<class charT, class traits>
    void f(basic_ios<charT,traits>& str, charT c) {
        // set fill character
        str.fill(c);
    }
    

    out << setfill(c)には typebasic_ostream<charT, traits>&と valueが必要ですout

    したがってfill()、27.5.5.3/14 で説明されているストリームの関数を呼び出します。

    char_type fill(char_type fillch);
    事後条件:traits::eq(fillch, fill())

    つまり、ストリームの特性の一部であるプロパティを変更します。特性は明示的に変更されるまで (次の出力フィールドだけでなく) 有効であると言えば十分です。

  2. 状況は、 27.5.6.2 /3 で説明されているように、ストリームの調整フィールド パラメータstd::leftを設定するの場合と同様です。

    ios_base& left(ios_base& str);
    効果: 通話str.setf(ios_base::left, ios_base::adjustfield).

  3. std::setw、一方、27.7.5/7に記載されています

    unspecifiedsetw(int n);
    戻り値: out が のインスタンスであるbasic_ostream<charT, traits>場合、式out << setw(n)が を呼び出したかのように動作するf(out, n)、または in が型のオブジェクトである場合、basic_istream<charT, traits>式が をin >> setw(n)呼び出したかのように動作する、未指定の型のオブジェクトf(in, n)。関数fは次のように定義されます。

    void f(ios_base& str, int n) {
      // set width
      str.width(n);
    }
    

    式 out << setw(n) は、型 basic_ostream& と値 out を持つ必要があります。>> setw(n) の式は、型 basic_istream& と値 in を持つ必要があります。

    実際、フォーマットされた出力操作が発生した後、プロパティwidthはにリセットされます。0たとえば、operator<<文字列に適用される場合 (つまり、<<-syntax を使用して文字列を出力する場合) の説明では、操作の順序は 27.7.3.6.4/5 で説明されています (私の強調):

    パディングは、22.4.2.2.2 で説明されているように決定されます。s で始まる n 文字は、out.widen(27.5.5.3) を使用して拡張されます。拡大された文字と必要なパディングが out に挿入されます。呼び出しますwidth(0)

    数値型 (27.7.3.6.2/1,2,3) の書式設定された出力操作の場合、std::num_put(これはstd::locale::facet) テンプレートを使用して数値を文字列に変換し、出力します。22.4.2.2 は、その操作がどのように実行されるかを詳細に説明し、その最後のステップ (文字列が出力された後) は、幅を0(22.4.2.2.2/5、ステージ 3、最後に) にリセットします。

    str.width(0)と呼ばれる

std:setwさまざまな IO マニピュレータの効果をさらに調査すると、実際には、次の (フォーマットされた) 出力操作でのみ有効になる唯一のマニピュレータであることがわかります。「スティッキー」な iomanipulatorも参照してください。、特にチャールズ・ベイリーの答え、さまざまなマニピュレーターの「粘着性」の比較。

于 2013-07-19T01:43:55.633 に答える