获取C ++输出流中元素的大小

问题描述 投票:2回答:2

我正在格式化一些日志输出。我希望最终结果看起来像这样:

Foo.................................12.1
Bar....................................4
Foo Bar............................42.01

总宽度是恒定的,但是两个参数(名称和值)都有不同的大小。一旦包含在std :: ostream中,有没有一种干净的方法来获取给定参数的宽度?

#include <iostream>

struct Entry {
    std::string name_;
    double value_;
};

constexpr int line_width = 30;

std::ostream& operator<<(std::ostream& log, const Entry& e)
{
    log << e.name_
        << std::string(line_width - e.name_.size(), '.') \\ should subtract the width of e.value_
        << e.value_;
    return log;
}

int main()
{
    Entry foo    = { "Foo", 12.1 };
    Entry bar    = { "Bar", 4};
    Entry foobar = { "Foo Bar", 42.01};

    std::cout << foo << '\n' << bar << '\n' << foobar << '\n';
}

上面的代码不起作用,因为我没有减去值的宽度。我正在考虑编写一个可以执行以下操作的函数:

template <typename T>
int get_width(std::ostream& log, T value)
{
    // 1. use tellp to get initial stream size
    // 2. insert the value in the stream
    // 3. use tellp to get final stream size  
    // 4. remove the value from the stream (is that even possible?)
    // 5. return the size = final - initial 
}

有没有达到目标的干净方法?

c++ stream ostream
2个回答
0
投票

您可以创建一个包含“名称”的字符串,以及一个包含“值”的字符串。

然后,很容易计算这两个字符串的总长度,并据此计算它们之间所需的空间。


0
投票

如前所述,这个问题有点像X-Y问题,因为您不需要知道宽度即可获得所需的输出。为此,应该知道字段的总宽度并使用合适的填充字符就足够了。

这应该为您工作:

std::ostream& operator<<(std::ostream& log, const Entry& e)
{
    auto beg = log.tellp();
    log << e.name_;
    auto len = log.tellp() - beg;
    auto oldFill = log.fill();
    auto oldWidth = log.width();
    log.fill('.');
    log.width(line_width - len);
    log << e.value_;
    log.fill(oldFill);
    log.width(oldWidth);
    return log;
}
© www.soinside.com 2019 - 2024. All rights reserved.