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...
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];
....
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.
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
.
The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.