【问题标题】:How to properly use setw() to format output?如何正确使用 setw() 格式化输出?
【发布时间】:2020-06-14 07:51:18
【问题描述】:

我正在尝试将我的输出格式化为:

1 [tab] First Name: John [tab] Last Name: Smith [tab] Age: 20 [tab]daysInCourse: {35, 40, 55} Degree Program: Security

我当前的代码是:

{
    cout << left << setw(15) << studentID;
    cout << left << setw(15) << "First Name: " << FN;
    cout << left << setw(15) << "Last Name: " << LN;
    cout << left << setw(15) << "Email " << studentEmail;
    cout << left << setw(15) << "Age: " << age;
    cout << left << setw(15) << "{" << days[0] << ", " << days[1] << ", " << days[2];
    cout << left << setw(15) << "Degree Program: ";
}

我玩过每一行的 setw 值,但似乎无法正确处理。 setw 函数是否只需要与特定值一起使用?

【问题讨论】:

  • std::setw(...) 仅适用于下一个类似字符串的对象。所以它将适用于“名字:”,但不适用于FN。您需要为每个类似字符串的对象调用std::setw(...)。不过,您只需为每个输出流调用一次std::left

标签: c++ c++11 format cout setw


【解决方案1】:

注意:我担心您发布的数据包含真实的电子邮件地址和有关真实人物的信息,这些信息可能会或可能不会是私人和受保护的。如果是这样的话,我认为这是对隐私的侵犯,这是非法的。即使征得同意,也无需在此论坛上发布私人数据;我建议您从您的帖子中删除这些数据,并且以后不要再这样做了。

在cmets中提到,setw操纵符只适用于下一个字符串,所以

cout << left << setw(15) << "{" << days[0] << ", " << days[1] << ", " << days[2];

将仅为字符{ 设置宽度为15(类似于"First Name: " 等)。还值得注意的是,如果一个字符串超过了指定的宽度,那么它将推送下一个内容并破坏列的对齐方式;所以你需要考虑最大可能的内容来设置宽度。

这是一个实现您想要的工作示例,使用stringstream 在打印之前形成字符串(以便setw 应用于整个事物):

#include <iostream>
#include <iomanip>
#include <sstream>
#include <string>
#include <vector>

// ------------------------------------------------------------------------

struct Student 
{
    std::string ID, First, Last, Email, Degree;
    unsigned age;
    std::vector<unsigned> days;

    Student( std::string ID, std::string First, std::string Last, unsigned age, 
        std::string Email, std::string Degree, std::vector<unsigned> days ) 
    : ID(ID), First(First), Last(Last), age(age), Email(Email), Degree(Degree), days(days)
    {}
};

std::ostream& operator<< ( std::ostream& os, const Student& s ) {
    std::ostringstream ss;

    ss << "First Name: " << s.First;
    os << std::left << std::setw(25) << ss.str();
    ss.str("");

    ss << "Last Name: " << s.Last;
    os << std::left << std::setw(35) << ss.str();
    ss.str("");

    ss << "Email: " << s.Email;
    os << std::left << std::setw(50) << ss.str();
    ss.str("");

    ss << "Age: " << s.age;
    os << std::left << std::setw(10) << ss.str();
    ss.str("");

    ss << "{" << s.days.at(0) << ", " << s.days.at(1) << ", " << s.days.at(2) << "}";
    os << std::left << std::setw(20) << ss.str();
    ss.str("");

    ss << "Degree Program: " << s.Degree;
    os << std::left << std::setw(30) << ss.str();
    ss.str("");

    return os << std::endl;
}

// ------------------------------------------------------------------------

int main() {
    std::cout << Student("A3","Robert","Smith",19,"example@foo.com","SOFTWARE",{20,40,33});
    std::cout << Student("A4","Alice","Smith",22,"example@bar.net","SECURITY",{50,58,40});
}

输出:

First Name: Robert       Last Name: Smith                   Email: example@foo.com                            Age: 19   {20, 40, 33}        Degree Program: SOFTWARE      
First Name: Alice        Last Name: Smith                   Email: example@bar.net                            Age: 22   {50, 58, 40}        Degree Program: SECURITY 

请注意,我为每个字段设置了不同的宽度,具体取决于内容的预期长度。例如,电子邮件地址可以很长,但年龄很少会超过两位数。

【讨论】:

    猜你喜欢
    • 2014-02-27
    • 1970-01-01
    • 2016-04-16
    • 1970-01-01
    • 1970-01-01
    • 2016-07-23
    • 2020-02-22
    • 1970-01-01
    • 2022-08-15
    相关资源
    最近更新 更多