在C++中将输出右对齐

7
#include<iostream>
#include<iomanip>
using namespace std;

int main()
{
    cout << right << "Hello" << setw(10) << "World\n";
    cout << right << "Goodbye"  << setw(10) << "World\n";
}

为什么这会导致类似以下输出的结果:
Hello    World
Goodbye    World

与其:

Hello    World
Goodbye  World

在这里我做错了什么?
编辑:
#include<iostream>
#include<iomanip>
using namespace std;

int main()
{
    cout    << "Hello"  <<  " World";
    cout << right << setw(10) << "today\n";
    cout   << "Goodbye"  <<  " World";
    cout << right << setw(10) << "today\n";
}

如果我尝试这样做,为什么“今天”这部分会对不齐?
4个回答

8

改变运算符的顺序以解决这个问题:

#include <iostream>
#include <iomanip>

int main()
{
    std::cout << std::left << std::setw(10) << "Hello" << "World\n";
    std::cout << std::left << std::setw(10) << "Goodbye" << "World\n";
    return 0;
}
  • 在你想要格式化的值之前,必须放置所有运算符。
  • 避免使用using namespace std

std::setw()运算符设置下一个值的字段宽度。而std::leftstd::right运算符则设置该字段中值的位置。

以下示例:

std::cout << std::left << std::setw(10) << "word1"
    << std::right << std::setw(20) << "word2" << std::endl;

将创建这种格式:

AAAAAAAAAABBBBBBBBBBBBBBBBBBBB
word1                    word2

你可以看到,有一个包含10个字符的第一个“字段”,其中放置了第一个文本内容,以及一个包含20个字符的第二个“字段”,使第二个单词右对齐。但如果第一个字段中的文本超过了这个字段的长度,就会发生这种情况:
AAAAAAAAAA....BBBBBBBBBBBBBBBBBBBB
word1istoolong               word2

第二个字段只是将字符数向右移动。流永远不会跟踪“当前位置”,它只是使用给定大小的“字段”构建输出。
要为给定页面调整文本对齐,请使用以下代码:
#include <iostream>
#include <sstream>
#include <list>

const int pageWidth = 78;
typedef std::list<std::string> WordList;

WordList splitTextIntoWords( const std::string &text )
{
    WordList words;
    std::istringstream in(text);
    std::string word;
    while (in) {
        in >> word;
        words.push_back(word);
    }
    return words;
}

void justifyLine( std::string line )
{
    size_t pos = line.find_first_of(' ');
    if (pos != std::string::npos) {
        while (line.size() < pageWidth) {
            pos = line.find_first_not_of(' ', pos);
            line.insert(pos, " ");
            pos = line.find_first_of(' ', pos+1);
            if (pos == std::string::npos) {
                pos = line.find_first_of(' ');
            }
        }
    }
    std::cout << line << std::endl;
}

void justifyText( const std::string &text )
{
    WordList words = splitTextIntoWords(text);

    std::string line;
    for (WordList::const_iterator it = words.begin(); it != words.end(); ++it) {
        if (line.size() + it->size() + 1 > pageWidth) { // next word doesn't fit into the line.
            justifyLine(line);
            line.clear();
            line = *it;
        } else {
            if (!line.empty()) {
                line.append(" ");
            }
            line.append(*it);
        }
    }
    std::cout << line << std::endl;
}

int main()
{
    justifyText("This small code sample will format a paragraph which "
        "is passed to the justify text function to fill the "
        "selected page with and insert breaks where necessary. "
        "It is working like the justify formatting in text "
        "processors.");
    return 0;
}

这个例子的作用是在开始时让每一行填充给定页面。它通过将文本分成单词,用这些单词填充行,并使每一行对齐以完全匹配宽度来实现。


@AlexanderTobiasHeinrich 抱歉,我复制了错误的示例。现在已经修复并按预期工作。 - Flovdis
2
@Flovdis 为什么应该避免使用 using namespace std - programstinator
如果cout像cout << "hello" << " world " << " today\n";,而你想要右对齐today怎么办? - user3340001
1
@user3340001 在这种情况下,只需将运算符*放在“today”字符串之前。所有运算符都应用于后续流中的所有值。 - Flovdis
@user3340001 或许我误解了你的问题。你能解释一下“右对齐”是什么意思吗? - Flovdis
显示剩余7条评论

5
问题是,在您调用setw的时候,输出流不会记得打印"Hello""Goodbye"

尝试使用以下代码以产生您想要的输出结果:
#include<iostream>
#include<iomanip>
using namespace std;

int main()
{
    cout << left << setw(10) << "Hello" << "World\n";
    cout << left << setw(10) << "Goodbye" << "World\n";
}

1
这是一个使用std::format(C++20)的解决方案:
#include <format>
#include <iostream>

int main() {
    std::cout << std::format("{:10}{:}\n", "Hello",   "World");
    std::cout << std::format("{:10}{:}\n", "Goodbye", "World");
    }

不幸的是,目前只有 MSVC >=19.29 默认支持 std::format根据 cppreference这里有一个运行示例。哦,当然在此期间 fmt::print 也是可行的... 无论如何,提供现代解决方案作为替代方案加1分 :-) - andreee

0

试试这个 -

    cout << right << "Hello" << "\t" << "World\n";
    cout << right << "Goodbye"  <<  "\t" << "World\n";

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接