如何在C++中轻松格式化数据表?

pea*_*ear 21 c++

我不确定,但我想我记得在Java中有一些东西可以指定一个字符串或数字开始离窗口左边有多远.

如何轻松格式化表格?我有这个(使用setw):

Bob Doe     10.96      7.61     14.39      2.11     47.30     14.21     44.58      5.00     60.23
Helen City     10.44      7.78     16.27      1.99     48.92     13.93     53.79      5.00     70.97
Joe Green     10.90      7.33     14.49      2.05     47.91     14.15     44.45      4.70     73.98
Run Code Online (Sandbox Code Playgroud)

理想情况下:

Bob           Doe        BLR  10.96   7.61  14.39   2.11  47.30  14.21  44.58   5.00  60.23  4:27.47
Helen         City       CUB  10.90   7.33  14.49   2.05  47.91  14.15  44.45   4.70  73.98  4:29.17
Joe           Green      USA  10.44   7.78  16.27   1.99  48.92  13.93  53.79   5.00  70.97  5:06.59
Run Code Online (Sandbox Code Playgroud)

计算的唯一方法是什么?还是有一些神奇的更简单的方法?

Cyr*_*oux 39

在C++中,您有三个功能可以帮助您按照自己的意愿行事.有定义<iomanip>.
- setw()帮助您定义输出的宽度.
- setfill()用你想要的角色填充其余部分(在你的情况下'').
- (或右)允许您定义对齐.

这是编写第一行的代码:

#include <iostream>
#include <iomanip>

using namespace std;

int main() {
    const char separator    = ' ';
    const int nameWidth     = 6;
    const int numWidth      = 8;

    cout << left << setw(nameWidth) << setfill(separator) << "Bob";
    cout << left << setw(nameWidth) << setfill(separator) << "Doe";
    cout << left << setw(numWidth) << setfill(separator) << 10.96;
    cout << left << setw(numWidth) << setfill(separator) << 7.61;
    cout << left << setw(numWidth) << setfill(separator) << 14.39;
    cout << left << setw(numWidth) << setfill(separator) << 2.11;
    cout << left << setw(numWidth) << setfill(separator) << 47.30;
    cout << left << setw(numWidth) << setfill(separator) << 14.21;
    cout << left << setw(numWidth) << setfill(separator) << 44.58;
    cout << left << setw(numWidth) << setfill(separator) << 5.00;
    cout << left << setw(numWidth) << setfill(separator) << 60.23;
    cout << endl;

    cin.get();
}
Run Code Online (Sandbox Code Playgroud)


编辑: 要减少代码,您可以使用模板功能:

template<typename T> void printElement(T t, const int& width)
{
    cout << left << setw(width) << setfill(separator) << t;
}
Run Code Online (Sandbox Code Playgroud)

你可以像这样使用:

printElement("Bob", nameWidth);
printElement("Doe", nameWidth);
printElement(10.96, numWidth);
printElement(17.61, numWidth);
printElement(14.39, numWidth);
printElement(2.11, numWidth);
printElement(47.30, numWidth);
printElement(14.21, numWidth);
printElement(44.58, numWidth);
printElement(5.00, numWidth);
printElement(60.23, numWidth);
cout << endl;
Run Code Online (Sandbox Code Playgroud)

  • 永远不要使用`system("PAUSE")`因为它可能会导致一些未定义的效果.相反,调用`cin.get()`,这将更加跨平台. (3认同)

syn*_*tik 16

以下是我用于以有组织的表格形式显示数据的各种函数,以及演示可能的使用场景的示例.

因为这些函数使用的是字符串流,所以它们没有其他解决方案那么快,但对我来说这一点从不重要 - 计算瓶颈在其他地方.

使用字符串流的一个优点是函数改变了它们自己(内部范围)字符串流的精度,而不是改变静态cout精度.因此,您永远不必担心无意中以一种持续影响代码其他部分的方式修改精度.


显示任意精度

prd函数("print double"的缩写)只是以指定的精度打印double值.

/* Convert double to string with specified number of places after the decimal. */
std::string prd(const double x, const int decDigits) {
    stringstream ss;
    ss << fixed;
    ss.precision(decDigits); // set # places after decimal
    ss << x;
    return ss.str();
}
Run Code Online (Sandbox Code Playgroud)

以下只是一个变体,允许您在数字的左侧指定空白填充.这有助于显示表格.

/* Convert double to string with specified number of places after the decimal
   and left padding. */
std::string prd(const double x, const int decDigits, const int width) {
    stringstream ss;
    ss << fixed << right;
    ss.fill(' ');        // fill space around displayed #
    ss.width(width);     // set  width around displayed #
    ss.precision(decDigits); // set # places after decimal
    ss << x;
    return ss.str();
}
Run Code Online (Sandbox Code Playgroud)

中心对齐功能

此函数只是居中对齐文本,左右填充空格,直到返回的字符串与指定的宽度一样大.

/*! Center-aligns string within a field of width w. Pads with blank spaces
    to enforce alignment. */
std::string center(const string s, const int w) {
    stringstream ss, spaces;
    int padding = w - s.size();                 // count excess room to pad
    for(int i=0; i<padding/2; ++i)
        spaces << " ";
    ss << spaces.str() << s << spaces.str();    // format with padding
    if(padding>0 && padding%2!=0)               // if odd #, add 1 space
        ss << " ";
    return ss.str();
}
Run Code Online (Sandbox Code Playgroud)

表格输出的例子

因此,我们可以使用上面的函数prdcenter函数以下列方式输出表.

代码:

std::cout << center("x",10)       << " | "
          << center("x^2",10)     << " | "
          << center("(x^2)/8",10) << "\n";

std::cout << std::string(10*3 + 2*3, '-') << "\n";

for(double x=1.5; x<200; x +=x*2) {
    std::cout << prd(x,1,10)       << " | "
              << prd(x*x,2,10)     << " | "
              << prd(x*x/8.0,4,10) << "\n";
}
Run Code Online (Sandbox Code Playgroud)

将打印表格:

    x      |    x^2     |  (x^2)/8  
------------------------------------
       1.5 |       2.25 |     0.2812
       4.5 |      20.25 |     2.5312
      13.5 |     182.25 |    22.7812
      40.5 |    1640.25 |   205.0312
     121.5 |   14762.25 |  1845.2812
Run Code Online (Sandbox Code Playgroud)

右对齐和左对齐功能

当然,您可以轻松构建center右对齐或左对齐函数的变体,并添加填充空间以填充所需的宽度.以下是这样的功能:

/* Right-aligns string within a field of width w. Pads with blank spaces
   to enforce alignment. */
string right(const string s, const int w) {
    stringstream ss, spaces;
    int padding = w - s.size();                 // count excess room to pad
    for(int i=0; i<padding; ++i)
        spaces << " ";
    ss << spaces.str() << s;                    // format with padding
    return ss.str();
}

/*! Left-aligns string within a field of width w. Pads with blank spaces
    to enforce alignment. */
string left(const string s, const int w) {
    stringstream ss, spaces;
    int padding = w - s.size();                 // count excess room to pad
    for(int i=0; i<padding; ++i)
        spaces << " ";
    ss << s << spaces.str();                    // format with padding
    return ss.str();
}
Run Code Online (Sandbox Code Playgroud)

我敢肯定有很多更优雅的方法来做这种事情 - 当然还有更简洁的方法.但这就是我的意思.对我来说效果很好.


Alo*_*ave 0

假设您想要将输出格式化为类似于表格,那么您需要的是I/O 操纵器
您可以使用setw()操纵器设置输出宽度,使用setfill()设置填充字符。