如何识别C ++ while循环中的最后一次迭代?

时间:2010-01-24 03:48:20

标签: c++

我如何制作,以便最后一个玩家名称没有,所以它是:

Player online:
Jim, John, Tony

而不是

Player online:
Jim, John, Tony,

我的代码是:

bool Commands::whoIsOnline(Creature* c, const std::string &cmd, const std::string &param)
{
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;
}

11 个答案:

答案 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();
  ......  
}