C++ : Why I can't print a const char* with sprintf?
Solution 1
You're trying to return an array allocated on stack and its behaviour is undefined.
const char* Notation() const
{
char s[10];
int x=5;
sprintf(s, "%d", x);
return s;
}
here s
isn't going to be around after you've returned from the function Notation()
. If you aren't concerned with thread safety you could make s
static.
const char* Notation() const
{
static char s[10];
....
Solution 2
In both cases, it invokes undefined behavior, as Notation()
returns a local array which gets destroyed on returning. You're unlucky that it works in one case, making you feel that it is correct.
The solution is to use std::string
as:
std::string Notation() const
{
char s[10];
int x=5;
sprintf(s, "%d", x);
return s; //it is okay now, s gets converted into std::string
}
Or using C++ stream as:
std::string Notation() const
{
int x=5;
std::ostringstream oss;
oss << x;
return oss.str();
}
and then:
char str[50];
sprintf(str, "%s", Notation().c_str());
The benefit (and beauty) of std::ostringstream
(and std::string
) is that you don't have to know the size of output in advance, which means you don't have to use magic number such as 10
in array declaration char s[10]
. These classes are safe in that sense.
Solution 3
char s[10]
in Notation
is placed on stack so it gets destroyed after exit from Notation
function. Such variables are called automatic. You need to save your string in heap using new
:
char *s = new char[10];
But you have to free this memory manually:
char str[50];
const char *nt = Notation();
sprintf(str, "%s", nt);
printf("%s", str);
delete[] nt;
If you really use C++ then use built-in string
class like Nawaz suggested. If you somehow restricted to raw pointers then allocate buffer outside Notation
and pass it as destanation parameter like in sprintf
or strcat
.
Wartin
Updated on September 08, 2020Comments
-
Wartin over 3 years
What am I missing here ? It's driving me nuts !
I have a function that returns a const char*
const char* Notation() const { char s[10]; int x=5; sprintf(s, "%d", x); return s; }
Now in another part of the code I am doing this :
..... ..... char str[50]; sprintf(str, "%s", Notation()); ..... .....
but str remains unchanged.
If instead I do this :
..... ..... char str[50]; str[0]=0; strcat(str, Notation()); ..... .....
str is correctly set.
I am wondering why sprintf doesn't work as expected...