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