我知道如何编写一个重载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
在评论部分的建议。