This is very basic but so:
I want a string with 4 characteres: "abcd"
how must I declare a new string, like that?
char *newStr = new char[4]; // or -> char newStr[4];
strcpy(newStr, "abcd");
the null '\0' character must be on the size of the string, so new char[5]?
yes, \0 character is a part of string and you must allocate memory for it as well
Yes, the termination nul character is part of the string. So you need to allocate space for 5 characters:
char *newStr = new char[5];
strcpy(newStr, "abcd");
Don't forget to free the dynamically allocate memory once you are done using it as:
delete[] newStr;
Alternatively you can also do:
char newStr[] = "abcd";
In C++ it's better to use the string class for representing strings:
string newStr = "abcd";
You don't have "new" in C, but only in C++.
You could:
char* string = "abc";
or
char string[] = "abc";
or
char* string = (char*) malloc(sizeof(char) * 4);
strcpy(string, "abc");
string[3]='\0';
/* remember to free the used memory */
or
char string[] = { 'a', 'b', 'c', '\0' };
This should do the dirty work for you:
char newString[] = "abcd";
Also, yes, you need new char[5];
If this is C++ (seems re-tagged for what i've read), whats wrong with
std::string my_string = "abcd";
?
Isn't that what you are looking for ? I Could be missing something.
/ ------------------- string constructors ----------------
string emp(""); // constructs the "empty string"
string emp2; // constructs another "empty string"
string spc(" "); // constructs string containing " "
string sstr("Some string"); // string containing "Some string"
char frob[] = "Frobnitz";
string sfrob(frob); // constructs a C++ string containing
// "Frobnitz" from a C-style string
string bar = "foobar"; // string containing "foobar"
// ------------------- stdout, c_str() --------------------
Source: http://www-cs-students.stanford.edu/~sjac/c-to-cpp-info/string-class
If it is a string literal, you can do either of these:
char *string = "abcd";
char astring[] = "abcd";
If you want to know this for eventually copying strings, you can either have a buffer, or allocate memory, and space for '\0' is necessary, even though strlen("abcd") will return 4 because it does not count the terminator.
/* buffer way */
char string[5];
strcpy(string, "abcd");
/* allocating memory */
// char *ptr = malloc(5*sizeof(*ptr)); // question was retagged C++
char *ptr = static_cast<char*>(malloc(5*sizeof(*ptr));
strcpy(ptr,"abcd");
/* more stuff */
free(ptr);
Since the question has been retagged to C++, you can also use new and delete.
/* using C++ new and delete */
char *ptr = new char[5]; // allocate a block of 5 * sizeof(char)
strcpy(ptr, "abcd");
// do stuff
delete [] ptr; // delete [] is necessary because new[] was used
Or you could also use std::string.
Related
Let's suppose I've this code snippet in C++
char* str;
std::string data = "This is a string.";
I need to copy the string data (except the first and the last characters) in str.
My solution that seems to work is creating a substring and then performing the std::copy operation like this
std::string substring = data.substr(1, size - 2);
str = new char[size - 1];
std::copy(substring.begin(), substring.end(), str);
str[size - 2] = '\0';
But maybe this is a bit overkilling because I create a new string. Is there a simpler way to achieve this goal? Maybe working with offets in the std:copy calls?
Thanks
As mentioned above, you should consider keeping the sub-string as a std::string and use c_str() method when you need to access the underlying chars.
However-
If you must create the new string as a dynamic char array via new you can use the code below.
It checks whether data is long enough, and if so allocates memory for str and uses std::copy similarly to your code, but with adapted iterators.
Note: there is no need to allocate a temporary std::string for the sub-string.
The Code:
#include <string>
#include <iostream>
int main()
{
std::string data = "This is a string.";
auto len = data.length();
char* str = nullptr;
if (len > 2)
{
auto new_len = len - 2;
str = new char[new_len+1]; // add 1 for zero termination
std::copy(data.begin() + 1, data.end() - 1, str); // copy from 2nd char till one before the last
str[new_len] = '\0'; // add zero termination
std::cout << str << std::endl;
// ... use str
delete[] str; // must be released eventually
}
}
Output:
his is a string
There is:
int length = data.length() - 1;
memcpy(str, data.c_str() + 1, length);
str[length] = 0;
This will copy the string in data, starting at position [1] (instead of [0]) and keep copying until length() - 1 bytes have been copied. (-1 because you want to omit the first character).
The final character then gets overwritten with the terminating \0, finalizing the string and disposing of the final character.
Of course this approach will cause problems if the string does not have at least 1 character, so you should check for that beforehand.
As I know, if we declare char* in our program then it gives memory from read-only area, so we are not able to change a char at any position in the array.
char *ch = "sitaram";
ch[2] = 'y';
The above code will not run properly, as we are changing read-only memory.
One approach is we can declare our char array as
char ch[] = "sitaram";
and then we can change a value at an index.
Is there any way where I can change a char value at any index in a char*?
Use the modern C++ approach for mutable string values
std::string str{"sitaram"};
str[2] = 'y';
String literals (i.e. values enclosed in "") are by default of type const char[n] (where n is the length of the string literal +1 for the null character) in C++ and because of that they are immutable, any attempt to modify them results in undefined behavior.
When you say:
char *ch = "sitaram";
The compiler does the following:
it allocates the string "sitaram" at program start (static storage duration). This string can be put into read-only memory.
when your program arrives at this line, it allocates the pointer ch, and makes this pointer to point to the statically allocated "sitaram" string.
if you do ch[2] = 'y', then you're trying to modify the 3rd character of the statically allocated string. Usually, you get a crash (because it is in read-only memory)
On the other hand, if you do the following:
char ch[] = "sitaram";
When the program hit this line, it allocates memory for the array ch[] (for 8 chars), then copies the string "sitaram" into this memory. If you do ch[2] = 'y', then you modify this allocated memory, which is perfectly fine to do.
If you want to modify a string with char *, it should point to a memory which is modifiable. For example:
char ch[] = "sitaram";
char *xx = ch;
xx[2] = 'y'; // it is the same as ch[2] = 'y';
Using char arrays:
char text[] = "sitaram";
text[3] = 'o';
char * p = &text[0];
p[4] = 'x';
cout << text;
So in c++ a normal c-style string can be initiated like this:
char cString[] = "my string";
How can I do the same thing using dynamic memory?
Why doesn't this work?
char *charPtr;
charPtr = new char("make this the value of the c string");
You can't just initialize a c-style string like that.
First of all you need a pointer, that points to the beginning of the string. Then need to allocate enough memory to hold that string, which is the number of characters + the terminating '\0'. You should include cstring header, for strlen and strcpy. At last you need to copy the string to the memory block.
char *str; //pointer to string
str = new char[strlen("The string to copy")+1]; //allocate memory
//strlen returns the number of charaters of a string exluding the '\0', so we need to add 1
//either use a string constant, or another cstyle string, or input the length manually
strcopy(str, "The string to copy");//strcpy copies the content of the string constant to str
//be sure to set the last element of the string to '\0'
str[strlen(str)] = 0; // or '\0'
//if str has 5 char it returns 4 because the last is \0
//but the array goes from 0 to 4, so 4 is the last element
And dont forget to use delete [ ] str; if you get rid of the string!
This question already has answers here:
How do I concatenate const/literal strings in C?
(17 answers)
Closed 9 years ago.
I need to put "Hello World" in str3. How can I do this ?
const char *one = "Hello ";
char *two = "World";
char *str3;
You have to allocate void* malloc (size_t size); for str3 first then you can use sprintf to write in a string.
char *str3 = malloc(strlen(one) + strlen(two) + 1);
sprintf(str3, "%s%s", one, two); // ^ \0 termination
Adding #Nik Bougalis Suggestion:
One should know dynamic memory allocation in C. In my code I allocated using malloc() so latter in code when I don't need str3 we should explicitly deallocate memory using free() in C.
Also to avoid buffer-overflow always use snprintf instead of sprintf: So re-writing code as follows:
int length = strlen(one) + strlen(two) + 1;
char *str3 = malloc(length * sizeof(char));
snprintf(str3, length, "%s%s", one, two);
// write more code that uses str3
free(str3);
// now don't uses `str3`'s allocated memory
Read a book about C.
str3 = malloc(strlen(one) + strlen(two) + 1) ; // +1 for the 0 terminator
strcpy(str3, one) ;
strcat(str3, two) ;
...
free(str3) ; // frees allocated space when you are finished.
std::vector<char> v;
v.insert(v.end(), one, one + strlen(one));
v.insert(v.end(), two, two + strlen(two));
v.push_back('\0');
str3 = v.data();
String literals like "Hello" are stored in read-only memory, so you need to copy them somewhere where they can be modified.
So you must first allocate memory where the strings are to be stored. A simply char array will do. Then use strcpy() and strcat() to copy the string literals into that array.
I'm trying to copy a CString to a char* using memcpy() and I have difficulties doing it. In fact, only the first character is copied. Here is my code:
CString str = _T("something");
char* buff = new char();
memcpy(buff, str, str.GetLength() + 1);
After this, all that buff contains is the letter s.
You probably are mixing ASCII and Unicode strings. If compiling with Unicode setting, then CString stores a Unicode string (two bytes per character, in your case each second byte is 0 and thus looks like an ASCII string terminator).
If you want all ASCII:
CStringA str = "something";
char* buff = new char[str.GetLength()+1];
memcpy(buff, (LPCSTR)str, str.GetLength() + 1);
If you want all Unicode:
CStringW str = L"something";
wchar_t* buff = new wchar_t[str.GetLength()+1];
memcpy(buff, (LPCWSTR)str, sizeof(wchar_t)*(str.GetLength() + 1));
If you want it working on both settings:
CString str = _T("something");
TCHAR* buff = new TCHAR[str.GetLength()+1];
memcpy(buff, (LPCTSTR)str, sizeof(TCHAR) * (str.GetLength() + 1));
If you want to convert a Unicode string to an ASCII string:
CString str = _T("something");
char* buff = new char[str.GetLength()+1];
memcpy(buff, (LPCSTR)CT2A(str), str.GetLength() + 1);
Please also recognize the casts from str to LPCSTR, LPCWSTR or LPCTSTR and the corrected buffer allocation (need multiple characters and not only one).
Also, I am not quite sure if this is really what you need. A strdup for example looks much simpler than a new + memcpy.
You have only allocated memory to hold a char variable. To do what you intend, you need to allocate enough memory to hold the complete string.
CString str = _T("something");
LPTSTR buff = new TCHAR[(str.GetLength()+1) * sizeof(TCHAR)]; //allocate sufficient memory
memcpy(buff, str, str.GetLength() + 1);
You are
Only allocating one char, which won't be enough unless the CString is empty, and
copying the CString instance instead of the string it represents.
Try
CString str = _T("something");
int size = str.GetLength() + 1;
char* buff = new char[size];
memcpy(buff, str.GetBuffer(), size);