How would I make so that the last player name doesn't have a ,
so it's:
Player online:
Jim, John, Tony
and not
Player online:
Jim, John, Tony,
My code is:
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;
}
Use count() to determine the total length of an array. The iteration of the counter was placed at the bottom of the foreach() loop - $x++; to execute the condition to get the first item. To get the last item, check if the $x is equal to the total length of the array. If true , then it gets the last item.
Instead of thinking it like player + ","
think of it as "," + player
So you could do something like this (psuedo-code):
onFirstName = true
output = ""
for each player in players:
if onFirstName:
onFirstName = false
else:
output += ", "
output += player's name
of if your language supports it (Which c++ does):
if length of players > 0:
output = players[0]
for each player in players except players[0]:
output += ", " + player's name
else:
output = ""
I like the look of that last one, I'll have to invent a language that actually works like that.
change
while(iter != Player::listPlayer.list.end())
{
info += (*iter).second->getName() + ", ";
//...
with:
if(iter != Player::listPlayer.list.end()){
info += (*iter).second->getName();
++iter;
while(iter != Player::listPlayer.list.end()){
{
info += ", " + (*iter).second->getName();
//...
}
//...
}
alternatively, you can do something like this if you don't want the comma in front of a name after the info.clear():
while(iter != Player::listPlayer.list.end())
{
info += ", " + (*iter).second->getName();
// ...
player->sendTextMessage(MSG_STATUS_CONSOLE_BLUE, info.c_str()+2);
(Borrowing wallacoloo's pseudocode)
output = ""
for each player in players:
if output != ""
output += ", "
output += player's name
The easiest way is to simply remove the additional ", "
in the end:
if (!info.empty()) {
info.erase(info.size()-2);
}
You can use string join from .NET or Boost or some other library or write your own. Although it might be overkill for that particular function, it's the kind of thing that you'll probably use elsewhere in that project, and that you'll definitely reuse in another project.
If this were my code, I'd probably just check the string at the beginning of the loop and add the comma when it's not empty. It's nice to know how to handle similar situations when that workaround is not available, so here's an alternate:
while (iter != Player::listPlayer.list.end())
{
info += (*iter).second->getName();
++iter;
if (iter != Player::listPlayer.list.end())
info += ", ";
++count;
...
}
Instead of finding the last iteration, find the first iteration. Handle special cases at the beginning of the loop, have a definite "clean" state before doing the "real work," and perform the increment at the end.
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;
}
My solution involves a variable that starts out as the empty string and is set to ", "
after each iteration (which only has an effect after the first iteration). No special cases need to be checked.
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;
}
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With