Reputation: 2079
this post bases on the solution given here, a post on SO
I write a function to get a given file extension (string type), something like:
void GetFileExtension(string filename, char* extension)
{
vector<string> rec;
StrDelimit(filename, '.', rec);
//cout << rec[rec.size()-2].c_str()[1] << endl;
//extension = rec[rec.size()-2].c_str()[0];
//extension = &rec[rec.size()-2].c_str()[0];
string str = rec[rec.size()-2];
// conversion from string to char*
vector<char> writable(str.size() + 1);
std::copy(str.begin(), str.end(), writable.begin());
//cout << writable << endl;
extension = &writable[0];
}
StrDelimit works fine already which receives a string and delimits to vector of substrings by the given delimiter
I use the "//conversion from string to char*" as shown to return the result to calling main program
There is no compile error but the result is a string of meaningless characters. What's it the problem?
any help would be appreciated!
Thank you!
Upvotes: 0
Views: 1994
Reputation: 13089
char *extension is a temporary copy of the address of a string. To actually put new data into it, you'd have to copy data to the address that it holds.
Does this help?
#include <stdio.h>
#include <string.h>
void getStringInoExistingBufer(char* existingBufferOut)
{
strcpy(existingBufferOut, "someData");
}
void getStringIntoNonExistingBuffer(char **newBufferOut)
{
*newBufferOut = strdup("someOtherData");
}
int main()
{
char buffer1[100] = {};
char *buffer2 = NULL;
printf("buffer1 (before): '%s'\n", buffer1);
getStringInoExistingBufer(buffer1);
printf("buffer1 (after): '%s'\n", buffer1);
printf("\n\n");
printf("buffer2 (before): '%s'\n", buffer2);
getStringIntoNonExistingBuffer(&buffer2);
printf("buffer2 (after): '%s'\n", buffer2);
}
Output:
buffer1 (before): ''
buffer1 (after): 'someData'
buffer2 (before): '(null)'
buffer2 (after): 'someOtherData'
Upvotes: 1
Reputation: 180867
Firstly, you're not really returning anything;
void GetFileExtension(string filename, char* extension)
{
...
extension = &writable[0]; // Assignment to local variable
}
If you intend to update the char* passed in extension
, you'll need to pass it as a char**
(i.e. a pointer to your char*
).
Secondly, even if you fix that, you're attempting to return a pointer to data in a local variable;
void GetFileExtension(string filename, char* extension)
{
...
vector<char> writable(str.size() + 1); // Local variable
...
extension = &writable[0]; // writable disappears after this line
// and extension will point to invalid memory
}
Just returning an std::string
would simplify your code quite a bit.
Upvotes: 0
Reputation: 18096
Why not just return extension as std::string
?
For example:
std::string GetFileExtension(std::string filename)
{
std::vector<string> rec;
StrDelimit(filename, '.', rec);
std::string extension = rec[rec.size() - 2];
return extension;
}
Upvotes: 0
Reputation: 19445
your problem is you creating the data member writable
on the stack, and then point to it with extension
BUT the scope of writable is the function meaning that when the function returns writable
is been cleared leaving extension
pointing nothing.
you can allocated a dynamic buffer for the char* but that is more C approach than C++. If possible I would recommend changing the function type to return a string or a vector which will make it much easier, and you can change those types to char* whenever needed.
Upvotes: 0