0

我知道如何编写一个重载ostream<<运算符作为类对象的友元方法。我知道如何遍历单循环和双循环。但事实证明,试图实现特定目标text format是一项艰巨的挑战。

这是我的函数的样子:

std::ostream& operator<<( std::ostream& out, const DeckOfCards& deck  ) {
    for ( auto& c : deck.getDeck() ) {
        if ( c.get()->getValue() != "Joker" ) {
            out << c.get()->getValue() << " "
                << c.get()->getSuit() << ", ";
        } else {
            out << c.get()->getSuit() << " "
                << c.get()->getValue() << ", ";
        }
    }
    out << std::endl;

    return out;
}

我的主要内容很简单:

int main() {
    DeckOfCards deck1;
    DeckOfCards deck2( false );

    std::cout << "Standard Deck:\n" << deck1 << std::endl;
    std::cout << "Expanded Deck:\n" << deck2 << std::endl;

    return 0;
}

它的输出符合预期。

Standard Deck:
Ace Spades, 2 Spades...


Queen Diamonds, King Diamonds,

Expanded Deck:
Ace Spades, 2 Spades...

Queen Diamonds, King Diamonds, Little Joker, Big Joker,

是的,最后有一个逗号,因为我不关心它。以上仅用于测试我的类的构造是否有效。

我想编辑上面的operator<<重载,以便打印的显示如下所示:

Standard Deck:
Spades:   Ace, 2, 3, 4, 5, 6, 7, 8, 9, 10, Jack, Queen, King
Hearts:   Ace, 2, 3, 4, 5, 6, 7, 8, 9, 10, Jack, Queen, King
Clubs:    Ace, 2, 3, 4, 5, 6, 7, 8, 9, 10, Jack, Queen, King
Diamonds: Ace, 2, 3, 4, 5, 6, 7, 8, 9, 10, Jack, Queen, King

Expanded Deck:
Spades:   Ace, 2, 3, 4, 5, 6, 7, 8, 9, 10, Jack, Queen, King
Hearts:   Ace, 2, 3, 4, 5, 6, 7, 8, 9, 10, Jack, Queen, King
Clubs:    Ace, 2, 3, 4, 5, 6, 7, 8, 9, 10, Jack, Queen, King
Diamonds: Ace, 2, 3, 4, 5, 6, 7, 8, 9, 10, Jack, Queen, King
Little Joker, Big Joker

在使用 : 时,我更愿意尝试保持类似于上述循环的简单循环for( auto& e : container):我还想打印西装名称一次,然后为每套西装每行打印一次所有值。如果牌组被扩展,则同样适用,除​​了最后两张牌将位于单独的最后一行,如上所示。

在使用现代 c++ 时,我似乎无法弄清楚如何做间隔

for ( auto& e : container ) {
   ...
}

循环类型。我已经尝试在这里展示许多不同的东西,并尽可能缩短这个问题,任何建议都会非常有帮助。

如果您需要了解更多关于class DeckOfCards正在使用的内容,请随时询问:课程非常简单;它包含一个vector<shared_ptr<Card>>和一个布尔值来表示甲板是标准的还是扩展的,并且Card有 2 个字符串。

编辑

我根据用户的建议对上面的循环进行了一些调整:Mitchel0022用作% 13 == 0带有额外变量的条件。

布局非常接近我想要实现的目标。修改后的运算符现在看起来像:

std::ostream& operator<<( std::ostream& out, const DeckOfCards& deck  ) {

    int cardsPrinted = 0;
    const size_t width = std::string( "Diamonds: " ).size();

    for ( auto& c : deck.getDeck()  ) {
        if ( cardsPrinted % 13 == 0 && cardsPrinted < 52 ) {
            out << "\n" << std::setw( width ) << c.get()->getSuit() << ": ";
        } else if ( cardsPrinted < 52 ) {
            out << c.get()->getValue() << " ";

        }
        cardsPrinted++;
    }   
    out << std::endl;

    if ( !deck.isStandard() ) {
        out << std::setw( width ) << deck.getDeck()[52].get()->getSuit() << " "
            << deck.getDeck()[52].get()->getValue() << ", "
            << deck.getDeck()[53].get()->getSuit() << " "
            << deck.getDeck()[53].get()->getValue() << std::endl;
    }

    return out;
}

但是输出非常接近我想要的缺少 1 个元素,现在看起来像这样:

Standard Deck:

    Spades: 2 3 4 5 6 7 8 9 10 Jack Queen King
    Hearts: 2 3 4 5 6 7 8 9 10 Jack Queen King
     Clubs: 2 3 4 5 6 7 8 9 10 Jack Queen King
  Diamonds: 2 3 4 5 6 7 8 9 10 Jack Queen King

Expanded Deck:

    Spades: 2 3 4 5 6 7 8 9 10 Jack Queen King
    Hearts: 2 3 4 5 6 7 8 9 10 Jack Queen King
     Clubs: 2 3 4 5 6 7 8 9 10 Jack Queen King
  Diamonds: 2 3 4 5 6 7 8 9 10 Jack Queen King
    Little Joker, Big Joker

唯一没有打印的元素是 Ace。它正在跳过第一个值;可能与变量的if statement和当前值有关cardsPrinted

最终编辑

我所要做的就是将这一行添加到if语句中:

out << c.get()->getValue() << " ";

suit入溪流后。现在我的 DeckOfCards 类的输出显示看起来很干净,这要归功于用户Mitchel0022在评论部分的建议。

4

0 回答 0