Need to return a *char not address of...
Hi,
The following function is supposed to return a const char from a float. But instead the warning I get says it is returning the address of the local variable ans
Code:
#include <cstdio>
char *ftostr(float dVar)
{
char ans[20];
snprintf(ans, 20, "%f", dVar);
return ans;
}
How to achieve the return of a const char and not the address of ans?
Re: Need to return a *char not address of...
CORRECTION:
Hi,
The following function is supposed to return a const CHAR* from a float. But instead the warning I get says it is returning the address of the local variable ans
Code:
#include <cstdio>
char *ftostr(float dVar)
{
char ans[20];
snprintf(ans, 20, "%f", dVar);
return ans;
}
How to achieve the return of a const CHAR* and not the address of ans?
Re: Need to return a *char not address of...
First of all your function is not set up to return a const char. You need to declare it thusly:
Code:
const char *ftostr(float dVar) {...}
Secondly, you are returning a pointer to a local variable "ans". Notice how you have declared ans in the scope of that function. This means that once the function has returned, the pointer will no longer be valid. That's why the compiler warns you.
BJW
Re: Need to return a *char not address of...
Thanks sockman, I actually figured that out just a few minutes ago. But the return still comes up garbled symbol.
This is the fragment I am using in my Win32 project:
Code:
float fNum = GetDlgItemFlt(hwndDlgM, IDC_NUMBER);
fNum = (fNum / 2.54);
const CHAR*sNum = ftostr(fNum);
SetDlgItemText(hwndDlgM, IDC_CONVERTION, sNum);
Nevermind the GetDlgItemFlt(...) I am sure its not the problem (hopefully)
I think this test code below hold a partial answer but the cout is totally ignoring anything right of the decimal - which does not go out.
Code:
#include <cstdio>
#include <iostream>
const char *ftostr(float dVar)
{
char ans[20];
snprintf(ans, 20, "%f", dVar);
return ans;
}
int main()
{
double fNum;// = 3.145;
std::cout << "Enter a decimal value: ";
std::cin >> fNum;
const char *cNum = ftostr(fNum);
std::cout << *cNum << std::endl;
system("pause");
return 0;
}
Ultimately, this line:
Code:
SetDlgItemText(hwndDlgM, IDC_CONVERTION, sNum);
Will output the fully converted sNum.
Any suggestions or examples are humbly welcome.
Re: Need to return a *char not address of...
First of all I'd just do std::cout << cNum << std::endl; rather than passing a pointer to it...... but then there's also one or two things that could also do with changing before it works properly. Like sockman mentioned, you shouldn't be returning a pointer to something declared locally in the function. I'd change what you have to something more like this....
Code:
#include <cstdio>
#include <iostream>
const char *ftostr(float dVar, char* buffer)
{
// char ans[20];
snprintf(buffer, 20, "%f", dVar);
return buffer;
}
int main()
{
double fNum;// = 3.145;
std::cout << "Enter a decimal value: ";
std::cin >> fNum;
char buffer[20];
//const char *cNum = ftostr(fNum);
ftostr(fNum, buffer);
std::cout << buffer << std::endl;
system("pause");
return 0;
}
Re: Need to return a *char not address of...
Quote:
Originally Posted by
Morbane
I am sure its not the problem (hopefully)
I think this test code below hold a partial answer but the cout is totally ignoring anything right of the decimal - which does not go out.
Do not return pointers or references to local variables. Doing so is undefined behaviour.
Code:
#include <cstdio>
#include <iostream>
const char *ftostr(float dVar)
{
char ans[20];
snprintf(ans, 20, "%f", dVar);
return ans; // this is absolutely no good
}
So you must scrap this idea of returning a pointer to local variable and come up with another way of doing what you want. One way has been mentioned, and that is to pass the buffer to fill in, and you fill the buffer with the information.
The other way is to use container classes such as std::string or std::vector<char> instead of character arrays. If this is a C++ program, you shouldn't be writing functions in the way you wrote yours -- there is no need to.
Code:
#include <string>
//...
std::string ftostr(float dVar)
{
char ans[20];
snprintf(ans, 20, "%f", dVar);
return ans;
}
The trick is that on return, the char array is converted to a std::string, so you are not returning a pointer or reference to a local variable. A much safer approach:
Code:
#include <string>
#include <sstream>
//...
std::string ftostr(float dVar)
{
std::ostringstream strm;
strm << dVar;
return strm.str();
}
Now there is no chance of buffer overflow.
Regards,
Paul McKenzie
Re: Need to return a *char not address of...
I found the solution - it is similar to Paul's suggestion. If there are any potential problems such as buffer overflow or something like, please let me know.
Here is the function I am using:
Code:
char* ftochar(double val)
{
stringstream ss (stringstream::in | stringstream::out);
ss << val;
string test = ss.str();
char * cstr;
cstr = new char [test.size()+1];
strcpy (cstr, test.c_str());
return cstr;
}
It works to pass the value into the Win32 function below nicely - so far:
Code:
SetDlgItemText(hwndDlgM, IDC_CONVERTION, (CHAR*)sNum);
THANKS for the replies everyone!
Re: Need to return a *char not address of...
Quote:
Originally Posted by
Morbane
I found the solution - it is similar to Paul's suggestion. If there are any potential problems such as buffer overflow or something like, please let me know.
The solutions were already given to you. Your 'solution' has a memory leak--new without delete.
Re: Need to return a *char not address of...
Quote:
Originally Posted by
Morbane
I found the solution - it is similar to Paul's suggestion. If there are any potential problems such as buffer overflow or something like, please let me know.
So who is responsible for cleaning up the call to "new"? Your program has a memory leak.
The solution is what I gave you. If a C++ program is resorting to strcpy() and char* to handle strings, then there better be a good reason to do that, with the person giving the reason a good C++ programmer before it can be accepted.
If the function returns a std::string such as my version, and then if you need to pass that to a function that takes a const char*, then use the c_str() member function.
Code:
std::string sNum;
sNum = // my version of the function in question, not yours.
SetDlgItemText(hwndDlgM, IDC_CONVERTION, sNum.c_str());
Regards,
Paul McKenzie
Re: Need to return a *char not address of...
Well - Thanks again!
I was a bit overexcited that I found something that worked - even if it was not a 'solution'.
I put Paul's code to use and I feel much better about things now.