How do I clone std::string contents to a new char[] array - c++

Given a std::string, how do I concisely (i.e. a single line/function call) allocate a char array freeable with delete[] of a suitable size and clone the string's contents into the char array as a null terminated string?
I could do this:
m_name = new char[name.size() + 1];
(void)name.copy(m_name, name.size());
m_name[name.size()] = '\0';
But it is not concise. What I really need is a function like:
size_type std::basic_string::clone(CharT** dest);
CharT* std::basic_string::clone();
That doesn't exist as far as I can see.
A company I used to work for implemented their own standard library which included a strnewdup() function, which worked just like strdup() but using new, to avoid code duplication. Something like that would work fine, but I cannot find any reference to something like that in the standard C++ library.
I would prefer a solution that only uses the standard C++ library and not something like Boost or writing my own code.

The C++ library does not implement the required functionality.
Bummer.

Related

why is this filename parameter a char pointer instead of string?

There's a function provided by my uni that is supposed to read in a file. In the parameter, there's the fileName parameter. What I don't understand is why they're using a character pointer instead of a simple string?
Also, how would I call this function with a string filename then?
I'm running C++14 on Visual studio 2017 community edition.
double* read_text(char *fileName, int sizeR, int sizeC)
{
double* data = new double[sizeR*sizeC];
int i = 0;
ifstream myfile(fileName);
if (myfile.is_open())
{
while (myfile.good())
{
if (i > sizeR*sizeC - 1) break;
myfile >> *(data + i);
i++;
}
myfile.close();
}
else cout << "Unable to open file";
//cout << i;
return data;
}
Edit: I get it guys, it's stupid. I'll post a separate question then. Thanks for the fast response!
why is this filename parameter a char pointer instead of string?
Because the designer of the API chose to do so. Most people at Stack Overflow are not the author of that API, so we cannot answer this question accurately.
However, there is another similar question that we can answer: What are reasons to use character pointer as a string argument? Let me answer that question instead:
Not using std::string as an argument allows the user of the API to not create a std::string object. This may be useful when:
The API needs to be used in "freestanding" implementations that don't provide the standard library and thus have no std::string. This probably doesn't apply to your particular example since the implementation of the function uses the standard library, but I include this argument for completeness.
The API needs to be used on systems that provide no dynamic memory allocation, which std::string requires.
The dynamic memory allocation that creation of the string may require may be too slow in the context where the API is used (this won't apply to an API that is going to read from disk, but I include the argument here for completeness).
(const) char* makes it possible to use the API from C. This may be relevant because:
The API may have originally been written for C, and has been inherited to a code base that now uses C++, but the API has not been changed in order to maintain backwards compatibility.
Providing a C compatible API allows using the API from other languages that are able to interface with C. Many languages have support for C interfaces while very few languages have support for C++ interfaces.
Also, how would I call this function with a string filename then?
You can get a pointer to a null terminated string using the c_str member function. Unfortunately the API is badly designed and the argument is non-const, while the pointer returned by c_str is const. You can const_cast the constness of the argument away in order to call this function. This is "OK" because the function doesn't actually modify the pointed string.
If you can require C++17 standard and the source string is non-const, then the data member function will be simpler as it doesn't require const_cast. Prior to C++17 there was no non-const overload, so it would require the same const casting, and prior to C++11 the pointed string was not guaranteed to be null terminated.
To make it clear: Using a non-const string argument for this function is bad design - whether that argument is a character pointer to null terminated string, or a reference to std::string.
P.S.There are other, more serious problems:
The caller of the function cannot possibly know how many numbers were read from the file. There is no way of avoiding UB in case the file has less than sizeR*sizeC values.
Returning a bare pointer that owns dynamic memory resource is a very bad design.
The loop that reads from the file checks whether the read was successful after the value has already been added to the array and the value is never overwritten, so the last element written into the array is always has an unspecified value.

Are the methods in the <cstring> applicable for string class too?

I've tried out using memcpy() method to strings but was getting a "no matching function call" although it works perfectly when I use an array of char[].
Can someone explain why?
www.cplusplus.com/reference/cstring/memcpy/
std::string is an object, not a contiguous array of bytes (which is what memcpy expects). std::string is not char*; std::string contains char* (somewhere really deep).
Although you can pull out the std::string inner byte array by using &str[0] (see note), I strongly encourage you not to. Almost anything you need to do already is implemented as a std::string method. Including appending, subtracting, transforming and anything that makes sense with a text object.
So yes, you can do something as stupid as:
std::string str (100,0);
memcpy(&str[0],"hello world", 11);
but you shouldn't.
Even if you do need memcpy behaviuor, try to use std::copy instead.
Note: this is often done with C functions that expects some buffer, while the developer wants to maintain a RAII style in his code. So he or she produces std::string object but passes it as C string. But if you do clean C++ code you don't need to.
Because there's no matching function call. You're trying to use C library functions with C++ types.

dynamic allocation in c++

I am triing to save a .txt file into an object(c++). the problem is i dont know how big it is.
in c i would do it with a evl with the malloc() function but i have no idea how to do that in c++ or how to google that issue =/
Why not use std::ostringstream?
Or if you want to use an equivalent to malloc, use:
char *storage = new char[__size__];
....
delete[] storage;
But if your file is a binary file odds are you have a byte which is null. strlen won't work the way you expect it then.
You can also use std::string, std::vector<char> in which you can have any values and that can be converted to const char * easily.
why won't you save it as a string in a field of type std::string?
try:
myObj.someString = myFile.rdbuf();
You can use the new operator in C++, or better yet one of the standard library containers.
Try this: http://www.fredosaurus.com/notes-cpp/newdelete/50dynamalloc.html
Prefer using standard containers than raw dynamic allocation

Is there an equivalent way to do CString::GetBuffer in std::string?

Many Windows API, such as GetModuleFileName, etc... write output to char* buffer. But it is more convenient to use std::string. Is there a way to have them write to std::string (or std::wstring)'s buffer directly?
Sorry for my poor English. I'm not a native English speaker. -_-
Taworn T.
If you're using C++0x, then the following is guaranteed to work:
std::string s;
s.resize(max_length);
size_t actual_length = SomeApiCall(&s[0], max_length);
s.resize(actual_length);
Before C++0x the std::string contents is not guaranteed to be consecutive in memory, so the code is not reliable in theory; in practice it works for popular STL implementations.
use std::string::c_str() to retrieve a const char * that is null terminated.
std::string::data() also returns a const char * but that may not be null terminated.
But like zeuxcg says, I dont suggest you to write directly in that buffer.

use of char * vs std::string in different environments

I have been using std::string in my code. I was going to make a std::string and pass it by reference. However, someone suggested using a char * instead. Something about std::string is not reliable when porting code. Is that true? I have avoided using char * as I would need to do some memory management for it. Instead I find using the std::string much easier to use.
Basically I have a 10 digit output that I am storing in this string. Atm, I am not sure which would be better to use.
std::string is part of the C++ Standard, and has been since 1998. It is available in all the current C++ compilers. There really is no portability reason not to use it. If you have an API that needs to use a C-style string, you can use the std::string's c_str() member to get one from a string:
std::string s = "foo";
int n = strlen( s.c_str() );
In C++, almost every string should be std::string unless another library requires a cstring, in which case you should still be using an std::string and passing string.c_str(), unless you're using functions that work with buffers.
However, if you're writing a library and exporting functions, it's better to use const char* parameters rather than std::string parameters for portability.
Using a char * you are sure that you will not get portability issues among libraries.
If a library exports a function that uses an std::string, it might have problems communicating with another library that has been linked against a different version of the standard library.
I think that there is nothing to worry about unless you are going to provide some API to 3rd party.
Just use std::string
There's nothing unportable about std::string that isn't also an issue with char *. std::string actually uses a char * internally...
string is better. There is nothing unreliable about it on any platform. If you're worried about passing large classes, you can pass const references of your strings into functions. Makes coding faster and less bug prone.
In addition to the fact thata it's easier, std::string will probably be more efficient. Its small string optimization can keep the 10 digits in the std::string object itself, instead of putting them in another memory block off the heap.