Works for me: g++ on Linux
#include<iostream>
#include<string>
static const char * sql_backslash_to_underscore(const char * key)
{
if (!key) {
//ERROR0("got NULL key");
return NULL;
}
std::string rep = key;
std::replace(rep.begin(), rep.end(), '\\', '_');
return rep.c_str();
}
int main()
{
std::cout<<sql_backslash_to_underscore("acct\\username");
}
siddhant3s@Xion:~$ g++ tester.cpp -o tester
siddhant3s@Xion:~$ ./tester
acct_username
siddhant3s
Practically a Posting Shark
816 posts since Oct 2007
Reputation Points: 1,486
Solved Threads: 140
The 1st version was wrong on Windows, Linux or elsewhere. It returns a pointer to deallocated memory of local string data buffer.
The 2nd version works but it's a very dangerous (error-prone) approach to return a pointer to dynamically allocated (by non-standard function strdup) memory. It's so easy to get memory leak and it's too annoying to save returned pointer then free the memory.
Better change this function signature (and code) to
static std::string sql_backslash_to_underscore(const char * key)
{
std::string rep;
if (key) {
rep = key;
std::replace(rep.begin(),rep.end(),'\\','_');
}
return rep;
}
ArkM
Postaholic
2,001 posts since Jul 2008
Reputation Points: 1,234
Solved Threads: 348
>The thing is that the functions calling sql_backslash_to_underscore is expect a
>const char * instead of a std::string
If you don't have trouble changing the calling code, you can make a function call as : sql_backslash_to_underscore("Hello").c_str();
C-type functions which dealing with Cstrings usually let the caller code determine the output. Most of them has prototype as this:
void f(const char* input, char* output);
siddhant3s
Practically a Posting Shark
816 posts since Oct 2007
Reputation Points: 1,486
Solved Threads: 140
static const char * sql_backslash_to_underscore(const char * key)
{
if (!key) {
ERROR0("got NULL key");
return NULL;
}
char * dup = strdup(key);
char* ptr;
while( (ptr = strrchr(dup,'\\')) != NULL)
*ptr = '_';
return dup;
}
One problem with the above code is that the caller cannot call free() on aconst char* that is returned by the above function. So unless you typecast to remove the const there will be a memory leak.
int main()
{
const char* ptr = sql_backslash_to_underscore("acct\\username\\Program Files\\Debug");
cout << ptr << "\n";
free( (char*)ptr);
}
Ancient Dragon
Retired & Loving It
30,049 posts since Aug 2005
Reputation Points: 5,662
Solved Threads: 2,343
>Wouldn't this replicate the problem earlier?
No.
std::string sql_backslash_to_underscore(const char * key)
{
if (!key) {
//("got NULL key");
return NULL;
}
std::string rep = key;
std::replace(rep.begin(),rep.end(),'\\','_');
std::cout<<(void*)rep.c_str();//lets see what is the location of the cstring of rep
return rep;//note: it is now returning *copy* of rep.
}
int main()
{
const char* a=sql_backslash_to_underscore("acct\\username").c_str();
std::cout<<std::endl<<(void*)a;//check the location of a
std::cout<<std::endl<<a ;
std::cout<<std::endl;
}
siddhant3s
Practically a Posting Shark
816 posts since Oct 2007
Reputation Points: 1,486
Solved Threads: 140
>>Won't making sql_backslash_to_underscore return strings break this?
Not if you are allowed to change that function.
std::strncpy(col, sql_backslash_to_underscore(col).c_str(), DB_MAX_TAB - 1);
Ancient Dragon
Retired & Loving It
30,049 posts since Aug 2005
Reputation Points: 5,662
Solved Threads: 2,343