简体   繁体   English

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

[英]Making an table with printf in c++

I'm trying to make a table like this.... (Just without the dots I used to separate the each item) 我正试图制作一张这样的桌子......(只是没有用来分隔每个项目的点)

Weekly Payroll: 每周工资表:

Name.....................Title.......Gross......Tax......Net 名称.....................标题....... ......总税收......网

Ebenezer Scrooge Partner 250.00 ..62.25 .187.75 Ebenezer Scrooge合伙人250.00 ..62.25 .187.75

Bob Cratchit ..........Clerk ......15.00 ....2.00 ..13.00 Bob Cratchit ..........职员...... 15.00 .... 2.00 ..13.00

This is what my code looks like for this part.... 这是我的代码看起来像这部分....

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); 
}

I have the first part of the table(the name part), but after that I dont know now to do the rest of the table. 我有表的第一部分(名称部分),但在那之后我现在不知道要做其余的表。 Can anyone help me? 谁能帮我?

Thanks 谢谢

You can use printf with left-justify flag (-). 您可以将printf与left-justify标志( - )一起使用。

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

Here is a sample program: 这是一个示例程序:

#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;
}

Output: 输出:

Name                     Title               Gross     Tax       Net
Bob Cratchit             Clerk               15.00     2.00      13.00

The most obvious question is: why use printf, when other tools are more adapt? 最明显的问题是:为什么使用printf,其他工具更适应? Another question, often forgotten, is what is the (final) output medium? 另一个经常被遗忘的问题是(最终)输出介质是什么? If the text is going to end up on a printer or in a text box in a windowing system, you may have your work cut out for you. 如果文本最终会出现在打印机上或窗口系统的文本框中,您可能会为自己的工作做好准备。 The fonts on such systems are rarely fixed width, so you'll have to take into account the width of the individual characters. 此类系统上的字体很少是固定宽度,因此您必须考虑单个字符的宽度。 For output to a printer, I would suggest outputting LaTeX and then postprocessing it. 为了输出到打印机,我建议输出LaTeX然后进行后处理。 For outputting to a window, the library you're using probably has some sort of table component which will do the formatting for you. 对于输出到窗口,您正在使用的库可能有某种表组件,它将为您进行格式化。

If you're outputing to some fixed width font device—a teletyp, for example, then you can either use iostream manipulators or user defined types. 例如,如果您输出的是某个固定宽度的字体设备 - 例如远程传输,那么您可以使用iostream操纵器或用户定义的类型。 (There's no way to do this cleanly with printf —you need iostreams.) Abstractly speaking, defining types like Name , Title and MonitaryAmount is the cleanest solution. (没有办法用printf干净地完成这个 - 你需要iostreams。)抽象地说,定义NameTitleMonitaryAmount等类型是最干净的解决方案。 In which case, you just define an appropriate << operator for the type. 在这种情况下,您只需为该类型定义一个合适的<<运算符。 Using a user defined type for name and title, instead of just std::string , may be overkill, however, and the manipulator approach may be preferred. 然而,使用用户定义的名称和标题类型而不仅仅是std::string可能是过度的,并且操纵器方法可能是首选。 (In a very large application, where the separate types would be justified, you're likely to need output in different contexts, and want manipulators to specify them as well.) (在一个非常大的应用程序中,单独的类型将被证明是合理的,您可能需要在不同的上下文中输出,并且希望操纵器也指定它们。)

In the simplest solution, you could get by with just two manipulators: TextField and MoneyField : each manipulator would take the field width as an argument to the constructor, and set the appropriate format fields in its << operator, eg: 在最简单的解决方案中,你可以只使用两个操纵器: TextFieldMoneyField :每个操纵器将字段宽度作为构造函数的参数,并在其<<运算符中设置适当的格式字段,例如:

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;
    }
};

and

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;
    }
};

(Practically speaking, it's probably better to use a class for Money. You'll want special rounding rules for multiplication, for example; if you're calculating tax, in fact, you'll probably need to use some sort of decimal type, rather than double , in order to meet legal requirements as to how it is calculated.) (实际上,使用Money类可能更好。例如,你需要特殊的乘法舍入规则;如果你计算税,事实上,你可能需要使用某种十进制类型,而不是double ,以满足关于如何计算的法律要求。)

Anyway, given the above manipulators, you can write something like: 无论如何,考虑到上面的操纵者,你可以写下这样的东西:

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;
}

(This assumes that you've cleaned up the rest to make it idiomatic and maintainable C++ as well.) (这假设您已经清理了其余部分,以使其成为惯用且可维护的C ++。)

Instead of using tabs to position at specific columns, use standard stream I/O manipulators . 使用标准流I / O操纵器 ,而不是使用选项卡定位在特定列。 To be more specific, check out std::setw and std::left . 更具体地说,请查看std::setwstd::left

Something like this: 像这样的东西:

std::cout << std::left << std::setw(25) << "Name" << std::setw(12) << "Title"
          << std::setw(11) << "Gross" << std::setw(9) << "Tax" << "Net\n";

You should not mix printf and cout - they use different buffering mechanisms and can lead you into all sort of problems. 你不应该混合printfcout - 他们使用不同的缓冲机制,可以引导你遇到各种各样的问题。 As you are using C++ stick with cout . 当你使用C ++坚持cout Look into setw and other manipulators to format the output as required. 查看setw和其他操纵器以根据需要格式化输出。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM