我如何制作,以便最后一个玩家名称没有,
所以它是:
Player online:
Jim, John, Tony
而不是
Player online:
Jim, John, Tony,
我的代码是:
bool Commands::whoIsOnline(Creature* c, const std::string &cmd, const std::string ¶m)
{
Player* player = dynamic_cast<Player*>(c);
if (player)
{
player->sendTextMessage(MSG_STATUS_CONSOLE_BLUE, "Players online: ");
AutoList<Player>::listiterator iter = Player::listPlayer.list.begin();
std::string info;
int count = 0;
while (iter != Player::listPlayer.list.end())
{
info += (*iter).second->getName() + ", ";
++iter;
++count;
if (count % 10 == 0)
{
player->sendTextMessage(MSG_STATUS_CONSOLE_BLUE, info.c_str());
info.clear();
}
}
if (!info.empty())
player->sendTextMessage(MSG_STATUS_CONSOLE_BLUE, info.c_str());
}
return true;
}
答案 0 :(得分:7)
而不是像player + ","
那样将其视为"," + player
所以你可以做这样的事情(伪代码):
onFirstName = true
output = ""
for each player in players:
if onFirstName:
onFirstName = false
else:
output += ", "
output += player's name
如果你的语言支持它(c ++的支持):
if length of players > 0:
output = players[0]
for each player in players except players[0]:
output += ", " + player's name
else:
output = ""
我喜欢最后一个的外观,我必须发明一种实际上就是这样的语言。
答案 1 :(得分:4)
变化
while(iter != Player::listPlayer.list.end())
{
info += (*iter).second->getName() + ", ";
//...
使用:
if(iter != Player::listPlayer.list.end()){
info += (*iter).second->getName();
++iter;
while(iter != Player::listPlayer.list.end()){
{
info += ", " + (*iter).second->getName();
//...
}
//...
}
或者,如果您不希望在info.clear()之后的名称前面使用逗号,则可以执行此类操作:
while(iter != Player::listPlayer.list.end())
{
info += ", " + (*iter).second->getName();
// ...
player->sendTextMessage(MSG_STATUS_CONSOLE_BLUE, info.c_str()+2);
答案 2 :(得分:3)
(借用wallacoloo的伪代码)
output = ""
for each player in players:
if output != ""
output += ", "
output += player's name
答案 3 :(得分:2)
最简单的方法是简单地删除最后的", "
:
if (!info.empty()) {
info.erase(info.size()-2);
}
答案 4 :(得分:2)
您可以使用.NET或Boost或其他库中的字符串连接或编写自己的库。虽然对于那个特定的函数可能有点过分,但是你可能会在该项目的其他地方使用它,并且你肯定会在另一个项目中重用它。
答案 5 :(得分:1)
如果这是我的代码,我可能只是在循环开始时检查字符串,并在它不为空时添加逗号。很高兴知道在没有可用的解决方法时如何处理类似的情况,所以这里有一个替代方案:
while (iter != Player::listPlayer.list.end())
{
info += (*iter).second->getName();
++iter;
if (iter != Player::listPlayer.list.end())
info += ", ";
++count;
...
}
答案 6 :(得分:1)
找到第一次迭代,而不是找到最后一次迭代。在循环开始时处理特殊情况,在执行“实际工作”之前具有明确的“清洁”状态,并在结束时执行增量。
while (iter != Player::listPlayer.list.end())
{
if ( count != 0 )
{
info += ", ";
if (count % 10 == 0)
{
player->sendTextMessage(MSG_STATUS_CONSOLE_BLUE, info.c_str());
info.clear();
}
}
// invariant: info is clean and ready to accept data
info += (*iter).second->getName();
++iter;
++count;
}
答案 7 :(得分:1)
我的解决方案涉及一个以空字符串开头的变量,并在每次迭代后设置为", "
(在第一次迭代后只有效果)。不需要检查特殊情况。
template<class ForwardIterator>
std::string sequence_to_string(ForwardIterator begin, ForwardIterator end)
{
std::string output;
const char* delimiter = "";
for (ForwardIterator it = begin; it != end; ++it)
{
output += delimiter;
output += *it;
delimiter = ", ";
}
return output;
}
答案 8 :(得分:0)
如果这是C ++并且是STL迭代器,那么如果迭代器是随机访问迭代器,那么你实际上可以问
if(iter + 1 == Plaer :: listPlayer.list.end())
如果您不允许这样做,那么您可能希望将代码放在while循环中,该循环在单独的函数中输出播放器的名称,并在while循环之前在第一个元素上调用该函数,然后调用它在while循环中。然后在while循环中调用打印逗号前打印逗号的代码。这样第一个调用将只打印第一个名称,然后while循环将始终首先打印一个逗号,然后是播放器的名称,这样输出总是以玩家的名字结束。
答案 9 :(得分:0)
我之前写了一些示例代码,以演示在C中执行此操作的几种不同方法:
http://www.taenarum.com/csua/fun-with-c/delimiter.c
不幸的是,没有哪种方法明显优于其他方法。我个人会采用传统方法(明确检查第一个或最后一个元素)以保持清晰并避免重复代码。 (绝对避免在C ++代码中使用goto
版本。)
答案 10 :(得分:0)
...
std::string info;
...
while (iter != Player::listPlayer.list.end())
{
if(info.size() > 0)
info += ",";
info += (*iter).second->getName();
......
}