Copy char num[50] to std::string - c++

How to copy contents of char array to std::string (not conversion)
Ex :
void CApp::ChangeState(GameState* state)
{
std::string strImagePath;
// cleanup the current state
if ( !states.empty() ) {
states.back()->Clean();
states.pop_back();
//states.back()->getImagePath( psImagepath );
}
// store and init the new state
states.push_back(state);
states.back()->Init();
//psImagepath = (char*)malloc(sizeof(char)*50);
states.back()->getImagePath( psImagepath );
printf("MenuState Init path %s\n",psImagepath);
}
i want to copy my contents into strImagePath (consider strImage path is declared in class definition)

Just use the string's constructor that takes a char array:
char arr[50];
//Fill your array, do stuff, etc, etc
<...>
std::string str(arr);
Note that the char array that you are passing to the constructor should be null-terminated.

You can use strImagePath.append(charArray) to append the char[], or strImagePath.assign(charArray) to replace the previous content of strImagePath by the char[] content.

Either use the constructor (std::string(const char* str)) or copy assignment operator (std::string& operator=(const char* str)).

Related

why this program behaves differently with different optimization flag value [duplicate]

I have a method which returns the constant char pointer. It makes use of a std::string and finally returns its c_str() char pointer.
const char * returnCharPtr()
{
std::string someString;
// Some processing!
return someString.c_str();
}
I have got a report from Coverity tool that the above is not a good usage. I have googled and have found that the char pointer returned would be invalidated as soon as someString meets its destruction.
Given this, how does one fix this issue? How can I return a char pointer accurately?
Returning std::string would resolve this issue. But I want to know if there is any other means of doing this.
What happens in this code is:
const char * returnCharPtr()
{
std::string someString("something");
return someString.c_str();
}
instance of std::string is created - it is an object with automatic storage duration
pointer to the internal memory of this string is returned
object someString is destructed and the its internal memory is cleaned up
caller of this function receives dangling pointer (invalid pointer) which yields undefined behavior
The best solution is to return an object:
std::string returnString()
{
std::string someString("something");
return someString;
}
When calling your function, DO NOT do this:
const char *returnedString = returnString().c_str();
because returnedString will still be dangling after the returned std::string is destructed. Instead store the entire std::string:
std::string returnedString = returnString();
// ... use returnedString.c_str() later ...
In C++, the simplest thing to do is to just return a std::string (which is also efficient thanks to optimizations like RVO and C++11 move semantics):
std::string returnSomeString()
{
std::string someString;
// some processing...
return someString;
}
If you really need a raw C char* pointer, you can always call .c_str() on the returned value, e.g.
// void SomeLegacyFunction(const char * psz)
// .c_str() called on the returned string, to get the 'const char*'
SomeLegacyFunction( returnSomeString().c_str() );
If you really want to return a char* pointer from the function, you can dynamically allocate string memory on the heap (e.g. using new[]), and return a pointer to that:
// NOTE: The caller owns the returned pointer,
// and must free the string using delete[] !!!
const char* returnSomeString()
{
std::string someString;
// some processing...
// Dynamically allocate memory for the returned string
char* ptr = new char[someString.size() + 1]; // +1 for terminating NUL
// Copy source string in dynamically allocated string buffer
strcpy(ptr, someString.c_str());
// Return the pointer to the dynamically allocated buffer
return ptr;
}
An alternative is to provide a destination buffer pointer and the buffer size (to avoid buffer overruns!) as function parameters:
void returnSomeString(char* destination, size_t destinationSize)
{
std::string someString;
// some processing...
// Copy string to destination buffer.
// Use some safe string copy function to avoid buffer overruns.
strcpy_s(destination, destinationSize, someString.c_str());
}
As this question is flagged C, do this:
#define _POSIX_C_SOURCE 200809L
#include <string.h>
const char * returnCharPtr()
{
std::string someString;
// some processing!.
return strdup(someString.c_str()); /* Dynamically create a copy on the heap. */
}
Do not forget to free() what the function returned if of no use anymore.
Well, COVERITY is correct. The reason your current approach will fail is because the instance of std::string you created inside the function will only be valid for as long as that function is running. Once your program leaves the function's scope, std::string's destructor will be called and that will be the end of your string.
But if what you want is a C-string, how about...
const char * returnCharPtr()
{
std::string someString;
// some processing!.
char * new_string = new char[someString.length() + 1];
std::strcpy(new:string, someString.c_str());
return new_string;
}
But wait... that's almost exactly as returning a std::string, isn't it?
std::string returnCharPtr()
{
std::string someString;
// some processing!.
return new_string;
}
This will copy your string to a new one outside of the function's scope. It works, but it does create a new copy of the string.
Thanks to Return Value Optimization, this won't create a copy (thanks for all corrections!).
So, another option is to pass the parameter as an argument, so you process your string in a function but don't create a new copy. :
void returnCharPtr(std::string & someString)
{
// some processing!.
}
Or, again, if you want C-Strings, you need to watch out for the length of your string:
void returnCharPtr(char*& someString, int n) // a reference to pointer, params by ref
{
// some processing!.
}
The best way would be to return an std::string, which does automatic memory management for you. If, on the other hand, you were really into returning a const char* which points to some memory allocated by you from within returnCharPtr, then it'd have to be freed by someone else explicitly.
Stay with std::string.
A solution which hasn't been evoked in the other answers.
In case your method is a member of a class, like so:
class A {
public:
const char *method();
};
And if the class instance will live beyond the usefulness of the pointer, you can do:
class A {
public:
const char *method() {
string ret = "abc";
cache.push_back(std::move(ret));
return cache.last().c_str();
}
private:
vector<string> cache; //std::deque would be more appropriate but is less known
}
That way the pointers will be valid up till A's destruction.
If the function isn't part of a class, it still can use a class to store the data (like a static variable of the function or an external class instance that can be globally referenced, or even a static member of a class). Mechanisms can be done to delete data after some time, in order to not keep it forever.
Your options are:
Return std::string
Pass a buffer to returnCharPtr() that will hold the new character buffer. This requires you to verify the provided buffer is large enough to hold the string.
Create a new char array inside returnCharPtr(), copy the buffer into the new one and return a pointer to that. This requires the caller to explicitly call delete [] on something they didn't explicitly create with new, or immediately place it into a smart pointer class.
This solution would be improved if you returned a smart pointer, but it really just makes more sense to return a std::string directly.
Choose the first one; return std::string.
It is by far the simplist and safest option.
The problem is that someString is destroyed at the end of the function, and the function returns the pointer to non-existing data.
Don't return .c_str() of string that could be destroyed before you use the returned char pointer.
Instead of...
const char* function()
{
std::string someString;
// some processing!
return someString.c_str();
}
//...
useCharPtr(function());
use
std::string function()
{
std::string someString;
// some processing!
return someString;
}
//...
useCharPtr(function().c_str());
If you have the freedom to change the return value of returnCharPtr, change it to std::string. That will be the cleanest method to return a string. If you can't, you need to allocate memory for the returned string, copy to it from std::string and return a pointer to the allocated memory. You also have to make sure that you delete the memory in the calling function. Since the caller will be responsible for deallocating memory, I would change the return value to char*.
char* returnCharPtr()
{
std::string someString;
// some processing!.
char* cp = new char[someString.length()+1];
strcpy(cp, someString.c_str());
return cp;
}
You can pass in a pointer to your string, and have the method manipulate it directly (i.e., avoiding returns altogether)
void returnCharPtr(char* someString)
{
// some processing!
if(someString[0] == 'A')
someString++;
}
I was facing this problem when implementing https://en.cppreference.com/w/cpp/error/exception/what what() virtual function of std::exception offspring.
Well the signature must be
virtual const char* what() const throw();
This means however that returning std::string is not an option unless you want to rewrite standard library. I would like to know what these people saying "always return std::string" would think about standard library developers...
To allocate dynamic array is not a good idea in exception handling. I end up with the following solution. The whole class will be just wrapper for the final message that could not be modified even inside constructor.
class KCTException : public exception
{
const char* file;
const int line;
const char* function;
const std::string msg;
const std::string returnedMessage;
public:
KCTException(std::string& msg, const char* file, int line, const char* function)
: file(file)
, line(line)
, function(function)
, msg(msg)
, returnedMessage(io::xprintf("KCTException in [%s#%s:%d]: %s", function, file, line, msg.c_str()))
{
}
const char* get_file() const { return file; }
int get_line() const { return line; }
const char* get_function() const { return function; }
const std::string& get_msg() const { return msg; }
const char* what() const throw()
{
return returnedMessage.c_str();
}
};
Here io::xprintf is my wrapper function that behaves as printf but returns string. I found no such function in a standard library.

C++ not correctly printing character pointer, displaying other characters [duplicate]

I have a method which returns the constant char pointer. It makes use of a std::string and finally returns its c_str() char pointer.
const char * returnCharPtr()
{
std::string someString;
// Some processing!
return someString.c_str();
}
I have got a report from Coverity tool that the above is not a good usage. I have googled and have found that the char pointer returned would be invalidated as soon as someString meets its destruction.
Given this, how does one fix this issue? How can I return a char pointer accurately?
Returning std::string would resolve this issue. But I want to know if there is any other means of doing this.
What happens in this code is:
const char * returnCharPtr()
{
std::string someString("something");
return someString.c_str();
}
instance of std::string is created - it is an object with automatic storage duration
pointer to the internal memory of this string is returned
object someString is destructed and the its internal memory is cleaned up
caller of this function receives dangling pointer (invalid pointer) which yields undefined behavior
The best solution is to return an object:
std::string returnString()
{
std::string someString("something");
return someString;
}
When calling your function, DO NOT do this:
const char *returnedString = returnString().c_str();
because returnedString will still be dangling after the returned std::string is destructed. Instead store the entire std::string:
std::string returnedString = returnString();
// ... use returnedString.c_str() later ...
In C++, the simplest thing to do is to just return a std::string (which is also efficient thanks to optimizations like RVO and C++11 move semantics):
std::string returnSomeString()
{
std::string someString;
// some processing...
return someString;
}
If you really need a raw C char* pointer, you can always call .c_str() on the returned value, e.g.
// void SomeLegacyFunction(const char * psz)
// .c_str() called on the returned string, to get the 'const char*'
SomeLegacyFunction( returnSomeString().c_str() );
If you really want to return a char* pointer from the function, you can dynamically allocate string memory on the heap (e.g. using new[]), and return a pointer to that:
// NOTE: The caller owns the returned pointer,
// and must free the string using delete[] !!!
const char* returnSomeString()
{
std::string someString;
// some processing...
// Dynamically allocate memory for the returned string
char* ptr = new char[someString.size() + 1]; // +1 for terminating NUL
// Copy source string in dynamically allocated string buffer
strcpy(ptr, someString.c_str());
// Return the pointer to the dynamically allocated buffer
return ptr;
}
An alternative is to provide a destination buffer pointer and the buffer size (to avoid buffer overruns!) as function parameters:
void returnSomeString(char* destination, size_t destinationSize)
{
std::string someString;
// some processing...
// Copy string to destination buffer.
// Use some safe string copy function to avoid buffer overruns.
strcpy_s(destination, destinationSize, someString.c_str());
}
As this question is flagged C, do this:
#define _POSIX_C_SOURCE 200809L
#include <string.h>
const char * returnCharPtr()
{
std::string someString;
// some processing!.
return strdup(someString.c_str()); /* Dynamically create a copy on the heap. */
}
Do not forget to free() what the function returned if of no use anymore.
Well, COVERITY is correct. The reason your current approach will fail is because the instance of std::string you created inside the function will only be valid for as long as that function is running. Once your program leaves the function's scope, std::string's destructor will be called and that will be the end of your string.
But if what you want is a C-string, how about...
const char * returnCharPtr()
{
std::string someString;
// some processing!.
char * new_string = new char[someString.length() + 1];
std::strcpy(new:string, someString.c_str());
return new_string;
}
But wait... that's almost exactly as returning a std::string, isn't it?
std::string returnCharPtr()
{
std::string someString;
// some processing!.
return new_string;
}
This will copy your string to a new one outside of the function's scope. It works, but it does create a new copy of the string.
Thanks to Return Value Optimization, this won't create a copy (thanks for all corrections!).
So, another option is to pass the parameter as an argument, so you process your string in a function but don't create a new copy. :
void returnCharPtr(std::string & someString)
{
// some processing!.
}
Or, again, if you want C-Strings, you need to watch out for the length of your string:
void returnCharPtr(char*& someString, int n) // a reference to pointer, params by ref
{
// some processing!.
}
The best way would be to return an std::string, which does automatic memory management for you. If, on the other hand, you were really into returning a const char* which points to some memory allocated by you from within returnCharPtr, then it'd have to be freed by someone else explicitly.
Stay with std::string.
A solution which hasn't been evoked in the other answers.
In case your method is a member of a class, like so:
class A {
public:
const char *method();
};
And if the class instance will live beyond the usefulness of the pointer, you can do:
class A {
public:
const char *method() {
string ret = "abc";
cache.push_back(std::move(ret));
return cache.last().c_str();
}
private:
vector<string> cache; //std::deque would be more appropriate but is less known
}
That way the pointers will be valid up till A's destruction.
If the function isn't part of a class, it still can use a class to store the data (like a static variable of the function or an external class instance that can be globally referenced, or even a static member of a class). Mechanisms can be done to delete data after some time, in order to not keep it forever.
Your options are:
Return std::string
Pass a buffer to returnCharPtr() that will hold the new character buffer. This requires you to verify the provided buffer is large enough to hold the string.
Create a new char array inside returnCharPtr(), copy the buffer into the new one and return a pointer to that. This requires the caller to explicitly call delete [] on something they didn't explicitly create with new, or immediately place it into a smart pointer class.
This solution would be improved if you returned a smart pointer, but it really just makes more sense to return a std::string directly.
Choose the first one; return std::string.
It is by far the simplist and safest option.
The problem is that someString is destroyed at the end of the function, and the function returns the pointer to non-existing data.
Don't return .c_str() of string that could be destroyed before you use the returned char pointer.
Instead of...
const char* function()
{
std::string someString;
// some processing!
return someString.c_str();
}
//...
useCharPtr(function());
use
std::string function()
{
std::string someString;
// some processing!
return someString;
}
//...
useCharPtr(function().c_str());
If you have the freedom to change the return value of returnCharPtr, change it to std::string. That will be the cleanest method to return a string. If you can't, you need to allocate memory for the returned string, copy to it from std::string and return a pointer to the allocated memory. You also have to make sure that you delete the memory in the calling function. Since the caller will be responsible for deallocating memory, I would change the return value to char*.
char* returnCharPtr()
{
std::string someString;
// some processing!.
char* cp = new char[someString.length()+1];
strcpy(cp, someString.c_str());
return cp;
}
You can pass in a pointer to your string, and have the method manipulate it directly (i.e., avoiding returns altogether)
void returnCharPtr(char* someString)
{
// some processing!
if(someString[0] == 'A')
someString++;
}
I was facing this problem when implementing https://en.cppreference.com/w/cpp/error/exception/what what() virtual function of std::exception offspring.
Well the signature must be
virtual const char* what() const throw();
This means however that returning std::string is not an option unless you want to rewrite standard library. I would like to know what these people saying "always return std::string" would think about standard library developers...
To allocate dynamic array is not a good idea in exception handling. I end up with the following solution. The whole class will be just wrapper for the final message that could not be modified even inside constructor.
class KCTException : public exception
{
const char* file;
const int line;
const char* function;
const std::string msg;
const std::string returnedMessage;
public:
KCTException(std::string& msg, const char* file, int line, const char* function)
: file(file)
, line(line)
, function(function)
, msg(msg)
, returnedMessage(io::xprintf("KCTException in [%s#%s:%d]: %s", function, file, line, msg.c_str()))
{
}
const char* get_file() const { return file; }
int get_line() const { return line; }
const char* get_function() const { return function; }
const std::string& get_msg() const { return msg; }
const char* what() const throw()
{
return returnedMessage.c_str();
}
};
Here io::xprintf is my wrapper function that behaves as printf but returns string. I found no such function in a standard library.

Strange const char* function return value behaviour [duplicate]

I have a method which returns the constant char pointer. It makes use of a std::string and finally returns its c_str() char pointer.
const char * returnCharPtr()
{
std::string someString;
// Some processing!
return someString.c_str();
}
I have got a report from Coverity tool that the above is not a good usage. I have googled and have found that the char pointer returned would be invalidated as soon as someString meets its destruction.
Given this, how does one fix this issue? How can I return a char pointer accurately?
Returning std::string would resolve this issue. But I want to know if there is any other means of doing this.
What happens in this code is:
const char * returnCharPtr()
{
std::string someString("something");
return someString.c_str();
}
instance of std::string is created - it is an object with automatic storage duration
pointer to the internal memory of this string is returned
object someString is destructed and the its internal memory is cleaned up
caller of this function receives dangling pointer (invalid pointer) which yields undefined behavior
The best solution is to return an object:
std::string returnString()
{
std::string someString("something");
return someString;
}
When calling your function, DO NOT do this:
const char *returnedString = returnString().c_str();
because returnedString will still be dangling after the returned std::string is destructed. Instead store the entire std::string:
std::string returnedString = returnString();
// ... use returnedString.c_str() later ...
In C++, the simplest thing to do is to just return a std::string (which is also efficient thanks to optimizations like RVO and C++11 move semantics):
std::string returnSomeString()
{
std::string someString;
// some processing...
return someString;
}
If you really need a raw C char* pointer, you can always call .c_str() on the returned value, e.g.
// void SomeLegacyFunction(const char * psz)
// .c_str() called on the returned string, to get the 'const char*'
SomeLegacyFunction( returnSomeString().c_str() );
If you really want to return a char* pointer from the function, you can dynamically allocate string memory on the heap (e.g. using new[]), and return a pointer to that:
// NOTE: The caller owns the returned pointer,
// and must free the string using delete[] !!!
const char* returnSomeString()
{
std::string someString;
// some processing...
// Dynamically allocate memory for the returned string
char* ptr = new char[someString.size() + 1]; // +1 for terminating NUL
// Copy source string in dynamically allocated string buffer
strcpy(ptr, someString.c_str());
// Return the pointer to the dynamically allocated buffer
return ptr;
}
An alternative is to provide a destination buffer pointer and the buffer size (to avoid buffer overruns!) as function parameters:
void returnSomeString(char* destination, size_t destinationSize)
{
std::string someString;
// some processing...
// Copy string to destination buffer.
// Use some safe string copy function to avoid buffer overruns.
strcpy_s(destination, destinationSize, someString.c_str());
}
As this question is flagged C, do this:
#define _POSIX_C_SOURCE 200809L
#include <string.h>
const char * returnCharPtr()
{
std::string someString;
// some processing!.
return strdup(someString.c_str()); /* Dynamically create a copy on the heap. */
}
Do not forget to free() what the function returned if of no use anymore.
Well, COVERITY is correct. The reason your current approach will fail is because the instance of std::string you created inside the function will only be valid for as long as that function is running. Once your program leaves the function's scope, std::string's destructor will be called and that will be the end of your string.
But if what you want is a C-string, how about...
const char * returnCharPtr()
{
std::string someString;
// some processing!.
char * new_string = new char[someString.length() + 1];
std::strcpy(new:string, someString.c_str());
return new_string;
}
But wait... that's almost exactly as returning a std::string, isn't it?
std::string returnCharPtr()
{
std::string someString;
// some processing!.
return new_string;
}
This will copy your string to a new one outside of the function's scope. It works, but it does create a new copy of the string.
Thanks to Return Value Optimization, this won't create a copy (thanks for all corrections!).
So, another option is to pass the parameter as an argument, so you process your string in a function but don't create a new copy. :
void returnCharPtr(std::string & someString)
{
// some processing!.
}
Or, again, if you want C-Strings, you need to watch out for the length of your string:
void returnCharPtr(char*& someString, int n) // a reference to pointer, params by ref
{
// some processing!.
}
The best way would be to return an std::string, which does automatic memory management for you. If, on the other hand, you were really into returning a const char* which points to some memory allocated by you from within returnCharPtr, then it'd have to be freed by someone else explicitly.
Stay with std::string.
A solution which hasn't been evoked in the other answers.
In case your method is a member of a class, like so:
class A {
public:
const char *method();
};
And if the class instance will live beyond the usefulness of the pointer, you can do:
class A {
public:
const char *method() {
string ret = "abc";
cache.push_back(std::move(ret));
return cache.last().c_str();
}
private:
vector<string> cache; //std::deque would be more appropriate but is less known
}
That way the pointers will be valid up till A's destruction.
If the function isn't part of a class, it still can use a class to store the data (like a static variable of the function or an external class instance that can be globally referenced, or even a static member of a class). Mechanisms can be done to delete data after some time, in order to not keep it forever.
Your options are:
Return std::string
Pass a buffer to returnCharPtr() that will hold the new character buffer. This requires you to verify the provided buffer is large enough to hold the string.
Create a new char array inside returnCharPtr(), copy the buffer into the new one and return a pointer to that. This requires the caller to explicitly call delete [] on something they didn't explicitly create with new, or immediately place it into a smart pointer class.
This solution would be improved if you returned a smart pointer, but it really just makes more sense to return a std::string directly.
Choose the first one; return std::string.
It is by far the simplist and safest option.
The problem is that someString is destroyed at the end of the function, and the function returns the pointer to non-existing data.
Don't return .c_str() of string that could be destroyed before you use the returned char pointer.
Instead of...
const char* function()
{
std::string someString;
// some processing!
return someString.c_str();
}
//...
useCharPtr(function());
use
std::string function()
{
std::string someString;
// some processing!
return someString;
}
//...
useCharPtr(function().c_str());
If you have the freedom to change the return value of returnCharPtr, change it to std::string. That will be the cleanest method to return a string. If you can't, you need to allocate memory for the returned string, copy to it from std::string and return a pointer to the allocated memory. You also have to make sure that you delete the memory in the calling function. Since the caller will be responsible for deallocating memory, I would change the return value to char*.
char* returnCharPtr()
{
std::string someString;
// some processing!.
char* cp = new char[someString.length()+1];
strcpy(cp, someString.c_str());
return cp;
}
You can pass in a pointer to your string, and have the method manipulate it directly (i.e., avoiding returns altogether)
void returnCharPtr(char* someString)
{
// some processing!
if(someString[0] == 'A')
someString++;
}
I was facing this problem when implementing https://en.cppreference.com/w/cpp/error/exception/what what() virtual function of std::exception offspring.
Well the signature must be
virtual const char* what() const throw();
This means however that returning std::string is not an option unless you want to rewrite standard library. I would like to know what these people saying "always return std::string" would think about standard library developers...
To allocate dynamic array is not a good idea in exception handling. I end up with the following solution. The whole class will be just wrapper for the final message that could not be modified even inside constructor.
class KCTException : public exception
{
const char* file;
const int line;
const char* function;
const std::string msg;
const std::string returnedMessage;
public:
KCTException(std::string& msg, const char* file, int line, const char* function)
: file(file)
, line(line)
, function(function)
, msg(msg)
, returnedMessage(io::xprintf("KCTException in [%s#%s:%d]: %s", function, file, line, msg.c_str()))
{
}
const char* get_file() const { return file; }
int get_line() const { return line; }
const char* get_function() const { return function; }
const std::string& get_msg() const { return msg; }
const char* what() const throw()
{
return returnedMessage.c_str();
}
};
Here io::xprintf is my wrapper function that behaves as printf but returns string. I found no such function in a standard library.

Does the address of the result of std::string::operator[] point to a writable, nul-terminated buffer?

I am modifying a function that accepts a const char* and uses a function, ProcessString. ProcessString is a function that expects a null-terminated character buffer as a char*. The characters in the buffer may or may not be modified, as defined by the function signature below. To "bridge the gap", I am using a temporary std::string:
void ProcessString( char* str );
void SomeFunction( const char* str )
{
string temp(str);
ProcessString( &temp[0] );
}
My primary question is about the guarantees of std::string::operator[] and whether the address returned by the &temp[0] above is a usable, null-terminated buffer as a char*. Secondly, and very much secondly, is there a better way to do this?
I am using C++03.
That only has well-defined behavior in C++11; in previous standards, std::string did not guarantee contiguous storage for its internal buffer.
However while that code is completely fine in C++11, the more idiomatic approach is to use std:vector<char>, which has guaranteed contiguous storage since C++03:
void ProcessString(char* str);
void SomeFunction(char const* str)
{
// + 1 for terminating NUL
std::vector<char> temp(str, str + std::strlen(str) + 1);
ProcessString(&temp[0]); // or temp.data() in C++11
}
I have created a small class to face this kind of problem, I have implemented the RAII idiom.
class DeepString
{
DeepString(const DeepString& other);
DeepString& operator=(const DeepString& other);
char* internal_;
public:
explicit DeepString( const string& toCopy):
internal_(new char[toCopy.size()+1])
{
strcpy(internal_,toCopy.c_str());
}
~DeepString() { delete[] internal_; }
char* str() const { return internal_; }
const char* c_str() const { return internal_; }
};
And you can use it as:
void aFunctionAPI(char* input);
// other stuff
aFunctionAPI("Foo"); //this call is not safe. if the function modified the
//literal string the program will crash
std::string myFoo("Foo");
aFunctionAPI(myFoo.c_str()); //this is not compiling
aFunctionAPI(const_cast<char*>(myFoo.c_str())); //this is not safe std::string
//implement reference counting and
//it may change the value of other
//strings as well.
DeepString myDeepFoo(myFoo);
aFunctionAPI(myFoo.str()); //this is fine
I have called the class DeepString because it is creating a deep and unique copy (the DeepString is not copyable) of an existing string.
If you need to go from a const char* to a char *, why not use strdup, and then free the buffer when ProcessString is done?
Going through std::string seems unnecessary to me.

C++: How would one implement their own String class?

I'm trying to re-learn C++ and was wondering if anyone could help me out here. I'm trying to implement my own String class to see if I can remember things, but I'm stuck on the constructor.
I have my header file and want to have a constructor as so:
Header File (MyFiles\String.h):
#ifndef STRING_
#define STRING_
using namespace std;
#include <iostream>
class String
{
private:
static const unsigned int MAX = 32; // Capacity of string
char Mem[MAX]; // Memory to hold characters in string
unsigned Len; // Number of characters in string
public:
// Construct empty string
//
String()
{
Len = 0;
}
// Reset string to empty
//
void reset()
{
Len = 0;
}
// Return status information
//
bool empty() const
{
return Len == 0;
}
unsigned length() const
{
return Len;
}
// Return reference to element I
//
char& operator[]( unsigned I )
{
return Mem[I];
}
// Return constant reference to element I
//
const char& operator[]( unsigned I ) const
{
return Mem[I];
}
// Construct string by copying existing string
//
String( const String& );
// Construct string by copying array of characters
//
String( const char [] );
// Copy string to the current string
//
String& operator=( const String& );
// Append string to the current string
//
String& operator+=( const String& );
};
// Compare two strings
//
bool operator==( const String&, const String& );
bool operator!=( const String&, const String& );
// Put a string into an output stream
//
ostream& operator<<( ostream&, const String& );
#endif
The bit I'm stuck on is this:
String::String(const String& str)
{
//what goes here?
}
Thanks!
Well, since it's a learning exercise.
I think you want to copy the contents of the other string here since this is a copy constructor. So you will want to copy across all the member variables. In your case
the copy constructor is not necessary because you've got a static array. If you had
dynamic memory (i.e. used new to allocate pointer to Mem) then you'd need this. However,
to show you how it's done, here you go.
String::String(const String& str)
{
//what goes here?
assert(str.Len < MAX); // Hope this doesn't happen.
memcpy(Mem, str.Mem, str.Len);
Len = str.Len;
}
You need to copy the data from str to this. The length is easy:
Len = str.Len; // or, equiv. this->Len= str.Len
The data is a little harder. You might use strcpy or memcpy, or even a for loop.
memcpy(Mem, str.Mem, sizeof Mem);
Good luck!
I concur with Kornel Kisielewicz: the fewer hand-rolled String classes, the better. But you're only doing this to learn, so fair enough :-). Anyway: your copy constructor needs to copy over the length and the contents of the Mem array, and that's it.
(If you were doing this to make something useful rather than as a learning exercise, I'd add: a string class with a fixed maximum string length -- especially one as small as 32 characters -- is a very bad idea indeed. But it's entirely reasonable if you don't feel like dealing with memory allocation and deallocation at the same time as you're trying to remember the even-more-basics...)