6

私はこのようなテーブルを作ろうとしています....(各アイテムを区切るために使用したドットなしで)

週次給与:

名称................................タイトル.......総額......税......正味

エベニーザー スクルージ パートナー 250.00 ..62.25 .187.75

ボブ・クラチット .........事務員 ......15.00 ....2.00 ..13.00

これは、この部分の私のコードがどのように見えるかです....

for (int count=0; count < numberOfEmployees; count++)
{
    cout << "Employee: \n";
    cout << "\t Name: ";
    cin.getline (employees[count].name, EMPLOYEESIZE); 

    cout << "\t Title: ";
    cin.getline (employees[count].title, EMPLOYEESIZE);

    cout << "\t SSNum: ";
    cin >> employees[count].SSNum;

    cout << "\t Salary: ";
    cin >> employees[count].Salary;

    cout << "\t Withholding Exemptions: ";
    cin >> employees[count].Withholding_Exemptions; 
    cin.ignore();

    cout << "\n";
}


double gross;
double tax;
double net;
double adjusted_income;

cout << "\n";

cout << "Weekly Payroll: \nName \t \t Title \t Gross \t Tax \t Net \n";


for (int count=0; count < numberOfEmployees; count++)
{
    gross = employees[count].Salary;
    adjusted_income = subtraction_times (employees[count].Salary, employees[count].Withholding_Exemptions);
    tax = adjusted_income * .25;
    net = subtraction (gross, tax);

    printf ("\n%s", employees[count].name); 
}

私はテーブルの最初の部分(名前の部分)を持っていますが、その後、テーブルの残りの部分を行う方法がわかりません。誰でも私を助けることができますか?

ありがとう

4

4 に答える 4

28

printf左寄せフラグ(-)とともに使用できます。

printf("%-10s", "title"); // this will left-align "title" in space of 10 characters

サンプルプログラムは次のとおりです。

#include <string>
using namespace std;

int main()
{
    string name = "Bob Cratchit";
    string title = "Clerk";
    float gross = 15;
    float tax = 2;
    float net = 13;

    printf("%-25s%-20s%-10s%-10s%-10s\n", "Name", "Title", "Gross", "Tax", "Net"); 
    printf("%-25s%-20s%-10.2f%-10.2f%-10.2f\n", name.c_str(), title.c_str(), gross, tax, net); 
    return 0;
}

出力:

Name                     Title               Gross     Tax       Net
Bob Cratchit             Clerk               15.00     2.00      13.00
于 2012-02-09T08:39:50.677 に答える
5

最も明白な質問は、他のツールがより適応しているのに、なぜprintfを使用するのかということです。忘れられがちなもう1つの質問は、(最終的な)出力メディアとは何かということです。テキストがプリンタまたはウィンドウシステムのテキストボックスに表示される場合は、作業内容を切り取ってもらうことができます。このようなシステムのフォントの幅が固定されることはめったにないため、個々の文字の幅を考慮する必要があります。プリンターに出力する場合は、LaTeXを出力して後処理することをお勧めします。ウィンドウに出力するために、使用しているライブラリには、おそらくフォーマットを行う何らかのテーブルコンポーネントがあります。

固定幅フォントデバイス(たとえば、テレタイプ)に出力する場合は、iostreamマニピュレーターまたはユーザー定義タイプのいずれかを使用できます。(これをきれいに行う方法はありませんprintf—iostreamが必要です。)抽象的に言えば、のようなタイプを定義するNameTitleMonitaryAmount最もクリーンなソリューションです。この場合、<<タイプに適切な演算子を定義するだけです。ただし、名前とタイトルに単にstd::stringではなくユーザー定義のタイプを使用するのはやり過ぎかもしれませんが、マニピュレータのアプローチが好まれる場合があります。(個別のタイプが正当化される非常に大規模なアプリケーションでは、さまざまなコンテキストでの出力が必要になる可能性が高く、マニピュレータにもそれらを指定する必要があります。)

最も単純なソリューションでは、2つのマニピュレーターだけでうまくいく可能性があります。 TextFieldおよびMoneyField:各マニピュレーターは、コンストラクターへの引数としてフィールド幅を取り、その<<演算子に適切なフォーマットフィールドを設定します。例:

class TextField
{
    int myWidth;
public:
    TextField( int width ) : myWidth( width ) {}
    friend std::ostream&
    operator<<( std::ostream& dest, TextField const& manip )
    {
        dest.setf( std::ios_base::left, std::ios_base::adjustfield );
        dest.fill( ' ' );
        dest.width( manip.myWidth );
        return dest;
    }
};

class MoneyField
{
    int myWidth;
public:
    MoneyField( int width ) : myWidth( width ) {}
    friend std::ostream&
    operator<<( std::ostream& dest, MoneyField const& manip )
    {
        dest.setf( std::ios_base::right, std::ios_base::adjustfield );
        dest.setf( std::ios_base::fixed, std::ios_base::floatfield );
        dest.fill( ' ' );
        dest.precision( 2 );
        dest.width( manip.myWidth );
        return dest;
    }
};

(実際には、Moneyのクラスを使用する方がおそらく良いでしょう。たとえば、乗算には特別な丸め規則が必要になります。実際、税金を計算する場合は、ある種の小数型を使用する必要があります。ではなくdouble、計算方法に関する法的要件を満たすためです。)

とにかく、上記のマニピュレータがあれば、次のように書くことができます。

TextField  name( 15 );
TextField  title( 8 );
MoneyField gross( 8 );
MoneyField tax( 6 );
MoneyField net( 8 );
for ( std::vector< Employee >::const_iterator employee = employees.begin();
        employee != employees.end();
        ++ employee ) {
    std::cout << name  << employee->name()
              << title << employee->title()
              << gross << employee->salary()
              << tax   << calculateTax( employee->salary() )
              << net   << calculateNet( employee->salary() )
              << std::endl;
}

(これは、残りの部分をクリーンアップして、慣用的で保守可能なC ++にすることを前提としています。)

于 2012-02-09T08:57:38.033 に答える
2

タブを使用して特定の列に配置する代わりに、標準ストリームI/Oマニピュレータを使用します。具体的には、チェックアウトしstd::setwてくださいstd::left

このようなもの:

std::cout << std::left << std::setw(25) << "Name" << std::setw(12) << "Title"
          << std::setw(11) << "Gross" << std::setw(9) << "Tax" << "Net\n";
于 2012-02-09T07:17:11.277 に答える
1

混合printfしないでくださいcout- これらは異なるバッファリングメカニズムを使用しており、あらゆる種類の問題につながる可能性があります。C++ を使用しているので、cout. および他のマニピュレータsetwを調べて、必要に応じて出力をフォーマットします。

于 2012-02-09T07:22:04.413 に答える