Not logged in, Join Here! or Log In Below:  
News Articles Search    

 Home / General Programming / Scalable console system with STL- problems Account Manager
Archive Notice: This thread is old and no longer active. It is here for reference purposes. This thread was created on an older version of the flipcode forums, before the site closed in 2005. Please keep that in mind as you view this thread, as many of the topics and opinions may be outdated.

January 17, 2005, 01:33 PM

well, as predicted, i'm having more C++ problems and need help, again :)

i'm trying to implement the console proposed in the Featured Articles section of flipcode ( so far, it's been going great- i've got it working, extended it to have a graphical part and got it displaying stuff, printing text to it, and accepting my input.

however, now that i come to use it, if i enter anything with a space in it (ie. a command or variable with an argument), the program goes into an infinite loop, and sine i don't fully understand strings, i'm not entirely sure why! here's the relevant section of code (copied exactly from the article):

  2. bool Console::parseCommandLine()
  3. {
  5. ...
  6.     std::string::size_type index = 0;
  7.     std::vector<std::string> arguments;
  9. ...
  11. // tokenize
  12.     while(index != std::string::npos)
  13.     {
  14.         // push word
  15.         std::string::size_type next_space = m_commandLine.find(' ');
  16.         arguments.push_back(m_commandLine.substr(index, next_space));
  17.                 // increment index
  18.         if(next_space != std::string::npos) index = next_space + 1;
  19.         else break;
  20.     }
  22. ...
  24. }

m_commandLine is a std::string, declared elsewhere in the Console object.

so, why does it go into a loop, and how do i fix it? i've stepped through the code, it seems that it keeps looping and finding the same space over and over, but not realising it's reached the end and looping forever.

Victor Widell

January 17, 2005, 07:09 PM

I have no idea why your code doesn't work, but I think I know how to fix it:

Declare m_commandLine as as stringstream instead.

  2. bool Console::parseCommandLine()
  3. {
  5. ...
  6.     std::string token;
  7.     std::vector<std::string> arguments;
  9. ...
  11. // tokenize
  12.     while(!m_commandLine.eof())
  13.     {
  14.         // push word
  15.         m_commandLine >> token;
  16.         arguments.push_back(token);
  17.     }
  19. ...
  21. }


January 17, 2005, 11:09 PM

std::string::size_type next_space = m_commandLine.find(' ');

It's finding the same space every time.

Use this:

std::string::size_type next_space = m_commandLine.find(' ', index);


January 18, 2005, 03:47 PM

well done, Reedbeta, i guess i should have noticed that, it's quite simple! works like a charm, now! thankin' ye kindly, sire!


January 26, 2005, 12:11 PM

well well, what a surprise, i've run into more problems... perhaps someone can help me again? :)

i'm now adding console functions to the mix, and having a problem that seems rather odd to me but i'm sure can be explained easily. i have these lines of code, not necessarily in the same file, or even the same class:

  2. #define getSingleton( classname )       classname::getInstance()
  3. .
  4. typedef void (*console_function)(const std::vector<std::string> &);
  5. .
  6. typedef struct
  7. {
  8. .       std::string name;
  9. .       console_item_type_t type;
  10. .       union
  11. .       {
  12. .               void *variable_pointer;
  13. .               console_function function;
  14. .       };
  15. } console_item_t;
  16. .
  17. void addItem(const std::string & strName, void *pointer, console_item_type_t type);
  18. .
  19. getSingleton(Console)->addItem("saysomething", saySomething, CTYPE_FUNCTION);
  20. .
  21. saySomething(const std::vector<std::string> & arguments) { ... }

now, when i try to compile this, i get this error, pointing to the line where i try to add the function:

error C2664: 'Console::addItem' : cannot convert parameter 2 from 'void (const std::vector &)' to 'void *'
. with
. [
. _Ty=std::string,
. _Ax=std::allocator
. ]

this seems a little odd to me, since surely these are the same? and i've used the same syntax as the guy who wrote the tutorial thingy did to add a function... can anybody tell me why what i'm doing is wrong, i really can't see why! thanks very much!

EDIT: oh, and i should probably mention that i've turned it into a singleton, hence the getSingleton() calls!


January 26, 2005, 12:37 PM

no actually they are not. C++ is very prickly about function pointers, if
you got that code from a tutorial, that tutorial can't be using C++, it has to be using C, since C is 'easy' when it comes to pointers v.s. function pointers,
check for a bit more info, but for now, here's a way
to rewrite it :

  2. #define getSingleton( classname )       classname::getInstance()
  4. void saySomething(const std::vector<std::string> & arguments)
  5. { ... }
  7. typedef void (*console_function)(const std::vector<std::string> &);
  9. typedef struct
  10. {
  11.         std::string name;
  12.         console_item_type_t type;
  13.         union
  14.         {
  15.                 void *variable_pointer;
  16.                 console_function function;
  17.         };
  18. } console_item_t;
  20. void addItem(const std::string & strName, console_function f, console_item_type_t type);
  21. //notice the change between using a 'void*" and a 'console_function' typedef
  22. //btw, where are you using console_item_t ?
  24. getSingleton(Console)->addItem("saysomething", saySomething, CTYPE_FUNCTION);


January 26, 2005, 04:19 PM

oh yeah, forgot about console_item_t... that's not relevant to this part of code! silly me.

anyways, the problem with that is, although it works, the console can also have items that aren't functions, which also get added by addItem. that's why it's a pointer, rather than just a console_function...

though thinking about it, i don't see a reason why i can't just overload the function- have one version that takes a pointer and a type, and one version that just takes the console_function... yes, that's what i'll do!

thanks for pointing out the error, though, i had no idea C++ function pointers were so hairy!


January 26, 2005, 04:26 PM

darn... i now have addItem taking a console_function instead of a pointer, and it still gives me an error:

error C2664: 'void Console::addItem(const std::string &,console_function)' : cannot convert parameter 2 from 'void (const std::vector &)' to 'console_function'

so, if it's not a void* and it's not a console_function, what on earth is it? i tried casting it to a console_function, but that just gives me an error telling me it can't be cast. eep!


January 29, 2005, 11:10 PM

can you post your project in a zip or something so we can DL it and see where the error is?


January 30, 2005, 07:35 AM

certainly :) i'm glad you want to help that much! note that i'm using VC++.NET, not sure if that has any relevance.

okay, here's a link:


February 09, 2005, 06:49 PM

i know i'm shamelessly bumping the thread here, but i know that a few people looked at the code. what have you found, if anything? i'm still rather stuck with this one, and unfortunately my university course doesn't cover any C++, so the only way i'll learn is if someone tells me what i'm doing wrong! thanks again, guys.


February 10, 2005, 03:35 PM

Looking at your code, it seems that the issue is that saySomething is a member of ConsoleFunctions:

  1. void ConsoleFunctions::saySomething(const std::vector<std::string> & arguments)

This isn't going to work as the parameter list will include an implicit this pointer. In order to make this work as a callback, make the member static in your header file:

  1. static void saySomething(const std::vector<std::string> & arguments);

Doing so makes the compile error go away for me.

Good luck!



February 11, 2005, 06:56 PM

thank you so much! that's much better, runs fine now.

the only thing is, surely approaching it in this way makes saySomething and defaultCommand global variables? and isn't that bad in terms of object orientation...?


February 12, 2005, 10:59 PM

hymerman wrote: the only thing is, surely approaching it in this way makes saySomething and defaultCommand global variables? and isn't that bad in terms of object orientation...?

They should still be defined as part of your class. They would be static members, which scopes them within the class but not within any particular object. It's a common way to do singletons as well: rather than instancing a class object, just create the class with all static members and call the functions without an object, like so:

  1. CClass::Function();

I think in general static member functions are the way to go when you need to pass a callback function to a routine; I will either do that or a file scope static function for that purpose. I have never tried to pass a regular member function as a callback function so I don't know the issues there.

This thread contains 14 messages.
Hosting by Solid Eight Studios, maker of PhotoTangler Collage Maker.