用c ++制作一个带printf的表

时间:2012-02-09 07:00:33

标签: c++ printf text-alignment

我正在尝试制作一张这样的桌子......(只是没有用来分隔每个项目的点数)

  

每周工资单:

     

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

     

Ebenezer Scrooge Partner 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 个答案:

答案 0 :(得分:22)

您可以将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

答案 1 :(得分:5)

最明显的问题是:为什么使用printf,当其他工具更多时 适应?另一个经常被遗忘的问题是(最终)输出是什么 介质?如果文本最终将在打印机或文本框中 一个窗口系统,你可能会为你的工作做好准备。字体 在这样的系统上很少固定宽度,所以你必须考虑到 记帐单个字符的宽度。输出到 打印机,我建议输出LaTeX,然后进行后处理。 要输出到窗口,您正在使用的库可能有一些 表格组件将为您进行格式化。

如果你要输出一些固定宽度的字体设备 - 一个远程传输,为 例如,您可以使用iostream操纵器或用户定义 类型。 (没有办法与printf干净利落地完成 - 你需要 iostreams。)抽象地说,定义像NameTitle这样的类型 而MonitaryAmount是最干净的解决方案。在这种情况下,你只是 为该类型定义适当的<<运算符。使用用户定义 名称和标题的类型,而不仅仅是std::string,可能是矫枉过正, 然而,操纵器方法可能是优选的。 (非常大 应用程序,你可能会使用不同的类型 需要在不同的上下文中输出,并希望操纵者指定 他们也是。)

在最简单的解决方案中,你可以通过两个操纵器来完成: TextFieldMoneyField:每个操纵者都会占据这个领域 width作为构造函数的参数,并设置适当的格式 其<<运算符中的字段,例如:

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 ++。)

答案 2 :(得分:2)

使用标准流I/O manipulators,而不是使用标签位于特定列。更具体地说,请查看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";

答案 3 :(得分:1)

您不应该混用printfcout - 他们使用不同的缓冲机制,可能会引发各种问题。当你使用C ++ stick cout时。查看setw和其他操纵器,根据需要格式化输出。