6

我正在尝试制作这样的表格......(只是没有我用来分隔每个项目的点)

每周工资:

名称............标题............总......税收......净

Ebenezer Scrooge 合伙人 250.00 ..62.25 .187.75

Bob Cratchit ....文员 ....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,而其他工具更适应?另一个经常被遗忘的问题是(最终)输出媒介是什么?如果文本最终会出现在打印机上或窗口系统的文本框中,那么您可能需要完成工作。此类系统上的字体很少是固定宽度的,因此您必须考虑各个字符的宽度。对于输出到打印机,我建议输出 LaTeX 然后对其进行后处理。为了输出到窗口,您使用的库可能具有某种表格组件,它将为您进行格式化。

如果您要输出到某个固定宽度的字体设备(例如电传打字机),那么您可以使用 iostream 操纵器或用户定义的类型。(没有办法干净地做到这一点printf——你需要 iostreams。)抽象地说,定义Name,Title 和之类的类型MonitaryAmount是最干净的解决方案。<<在这种情况下,您只需为该类型定义一个适当的运算符。然而,使用用户定义的名称和标题类型,而不是仅仅使用std::string,可能是多余的,并且操纵器方法可能是首选。(在一个非常大的应用程序中,单独的类型是合理的,您可能需要在不同的上下文中输出,并希望操纵器也指定它们。)

在最简单的解决方案中,您可以只使用两个操纵器: 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::setwstd::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 回答