This function can be used to convert anything printable (through cout, for example) to a C++ string:
// utility to convert anthing to a string #include <sstream> template<typename T> std::string tostring(const T& x) { std::ostringstream os; os << x; return os.str(); }
Put it towards the top of your program, then you can convert a number, for example, to a string like this:
int i; string mystring; i = 15; mystring = tostring(i);
FLTK (sadly) does not know about the standard C++ string class, but requires its textual information as C-style character arrays ("C strings"). For a message box or a label, you can use a literal string constant in double quotes "like this".
If the text you need is not constant, but you have it in a C++ string object (perhaps by using the tostring function above) you can just use its c_str() function, e.g:
string myname("Dogbert"); mybox->value(myname.c_str());
This works fine for the value() function, which makes for itself a private copy of the supplied string. However, if you are providing a label, either via the label() function, or as the last item in the constructor of a widget:
namebut = new Fl_Button(100,50,200,25, myname.c_str());
then you must not subsequently change the underlying C++ string, because that would invalidate the label (which by default is not copied, but just a pointer into the C++ string). The safest thing if you are using a string variable is to use copy_label(), which does make its own copy. You can leave the label out of the constructor, then immediately set it:
namebut = new Fl_Button(100,50,200,25); namebut->copy_label(myname.c_str());
Alternatively, you can define your own function to make a new a C-string from a C++ string:
#include <cstring> char* copycstr(std::string s) { char* cstr = new char[s.length() + 1]; std::strcpy(cstr, s.c_str()); return cstr; } // then... namebut = new Fl_Button(100,50,200,25, copycstr(myname));
This approach will also work for functions that need an unchanging copy, but which do not have a copy_ version, for example:
mywidget->tooltip(copycstr(myname));
The most general way of making a C-string from anything that can be output with the << insertion operator is to use a function like this (shorter solutions welcomed):
#include <sstream> // Convert to C-string. Caller responsible for delete[] template<typename T> char* makestr(const T& i) { std::ostringstream os; os << i; std::string oss = os.str(); char* sp = new char[oss.length()+1]; sp[oss.copy(sp, std::string::npos)] = 0; return sp; } // then you can say... int j = 42; mybutton->label(makestr(j));
The older strstream method is a bit shorter, but modern compilers are sniffy about it:
#include <strstream> // Convert to C-string. Caller responsible for delete[] template<typename T> char* makestr(const T& i) { std::ostrstream os; os << i << std::ends; return os.str(); // buffer claimed to outlive stream }
In all of these copy functions, the calling program owns the copied buffer. Clearly, if you don't delete[] it after all use of it has finished, you have a memory leak. This is unlikely to be a problem unless your program has the potential to make an unlimited number of copies.
Mark Colclough 17 Oct 2005, 7 Nov 2008, 3 Nov 2009