I have a function in a third-party library written in C: char* fix_filename_slashes(char* path)
. This function expects a mutable C-string passed to it so it can change all the slashes in the path to the correct use based on the operating system. All the strings I'm using in my Facade are declared as std::string
s. I attempted to simply use foo.c_str()
as every other function that expects a C string doesn't change it and expects a const char *
, but this function causes an error: Error: Argument of type "const char *" is incompatible with parameter of type "char *"
Is the result I came up with:
char* tempf = const_cast<char*>(filename.c_str());
filename = std::string(fix_filename_slashes(tempf));
tempf = NULL;
considered "correct" or are there other (more correct?) ways to accomplish the task?
EDIT
Whups. Apparently the function returns a COPY of the string. Still there are some nice answers already given.
A std::string_view can refer to both a C++ string or a C-string. All that std::string_view needs to store is a pointer to the character sequence and a length. std::string_view provides the same API that std::string does, so it is a perfect match for C-style string literals.
First, we have the function definition “DisplayString,” where a constant string reference is passed. The constant strings are defined and initialized in the main function as “str1” and “str2”. After that, pass these constant strings to the function “InputString”.
There is no functionality difference between string and std::string because they're the same type.
To pass a one dimensional string to a function as an argument we just write the name of the string array variable. In the following example we have a string array variable message and it is passed to the displayString function.
If the string length does not change, you can use a pointer to the first character of the string. This is undefined behavior in the C++03 standard, but all known implementations work properly and it is explicitly allowed under the C++11 standard.
fix_filename_slashes(&filename[0]);
If the size of the string may change, you'll have to do a little more work.
filename.resize(max_size, 0);
append_filename_suffix(&filename[0]);
filename.resize(strlen(filename.c_str()));
Convert it into a null-terminated sequence of characters stored in a std::vector
:
template <typename Character>
std::vector<Character> to_vector(std::basic_string<Character> const& s)
{
std::vector<Character> v;
v.reserve(s.size() + 1);
v.insert(v.end(), s.begin(), s.end());
v.push_back(0);
return v;
}
Usage example:
std::string filename = get_filename();
std::vector<char> filename_cstr = to_vector(filename);
filename = std::string(fix_filename_slashes(&filename_cstr[0]));
Since you are going to all the trouble you could just comply with the requirements of the C function and copy your string to a char array then after the function create a string from the char array or force a copy assignment on your original string.
char* temp = new char[str.size() + 1]
// Force a copy of the result into another string
str = (const char*)fix_filename_slashes(strncpy(temp, str.c_str(), str.size() + 1));
delete [] temp;
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With