This question already has answers here:
c++ array assignment of multiple values
(4 answers)
Closed 5 years ago.
I'm doing something like that:
char* test = "HELLO";
char* test2[6] = test; //
But it is not working, how can I achieve that?
You can't copy arrays in C++, at least not without a little help. In this case the function you need is strcpy
char* test = "HELLO";
char test2[6];
strcpy(test2, test);
Also note that an array of chars is char[] not char*[] (which is an array of char pointers).
You can only initialize an array with a string literal:
8.5.2 Character arrays [dcl.init.string]
1 An array of narrow character type (3.9.1), char16_t array, char32_t array, or wchar_t array can be initialized
by a narrow string literal, char16_t string literal, char32_t string literal, or wide string literal,
respectively, or by an appropriately-typed string literal enclosed in braces (2.13.5). Successive characters of
the value of the string literal initialize the elements of the array. [ Example:
char msg[] = "Syntax error on line %s\n";
I don't know the rationale for this but I'll take a guess and say that that it is meant to guarantee that direct initializations do not overflow the array (when the size is specified).
Related
This question already has answers here:
What happened when we do not include '\0' at the end of string in C?
(5 answers)
What is the difference between char s[] and char *s?
(14 answers)
Why do string literals (char*) in C++ have to be constants?
(2 answers)
Closed last year.
I am a C++ newbie. Although many similar questions have been asked and answered, I still find these concepts confusing.
I know
char c='a' // declare a single char c and assign value 'a' to it
char * str = "Test"; // declare a char pointer and pointing content str,
// thus the content can't be modified via point str
char str1[] = "Test"; // declare a char array str1 and assign "Test" to it
// thus str1 owns the data and can modify it
my first question is char * str creates a pointer, how does char * str = "Test"; work? assign a string literal to a pointer? It doesn't make sense to me although it is perfectly legal, I think we can only assign an address to a pointer, however "Test" is a string literal not an address.
Second question is how come the following code prints out "Test" twice in a row?
char str2[] = {'T','e','s','t'}; // is this line legal?
// intializing a char array with initilizer list, seems to be okay to me
cout<<str2<<endl; // prints out "TestTest"
why cout<<str2<<endl; prints out "TestTest"?
char * str = "Test"; is not allowed in C++. A string literal can only be pointed to by a pointer to const. You would need const char * str = "Test";.
If your compiler accepts char * str = "Test"; it is likely outdated. This conversion has not been allowed since C++11 (which came out over 10 years ago).
how does char * str = "Test"; work?
String literals are implicitly convertible to a pointer to the start of the literal. In C++ arrays are implicitly convertible to pointer to their first element. For example int x[10] is implicitly convertible to int*, the conversion results in &(x[0]). This applies to string literals, their type is a const array of characters (const char[]).
how come the following code prints out "Test" twice in a row?
In C++ most features related to character strings assume the string is null terminated, which is implied in string literals. You would need {'T','e','s','t','\0'} to be equivalent to "Test".
This question already has answers here:
What is the difference between char s[] and char *s?
(14 answers)
Closed 1 year ago.
char* a = "string"; /*"string" is a string literal, thus modifying
value isn't allowed, but then why */
char b[] = "string1"; /*"string1" is
also a string literal but why modification of this is allowed? */
a[1] = 's'; //this is not allowed b[1] = 'p'; //this is allowed
Why can char array be modified when it is clearly pointing to a string literal?
when it is clearly pointing to a string literal?
No. Given char b[] = "string1";, b is not a pointer pointing to the string literal, but a char array containing copy of "string1". The modification on the string literal leads to UB, but modification on the char array is fine.
String literals can be used to initialize character arrays. If an array is initialized like char str[] = "foo";, str will contain a copy of the string "foo".
BTW char* a = "string"; is not allowed since C++11; you have to write it as const char* a = "string";.
I'm a bit baffled that this is allowed:
char num[6] = "a";
What is happening here? Am I assigning a pointer to the array or copying the literal values into the array (and therefore I'm able to modify them later)?
Why can I assign a string literal less than the array itself? What is happening here?
This is well defined. When initialize character arrays with string literal,
If the size of the array is specified and it is larger than the number
of characters in the string literal, the remaining characters are
zero-initialized.
So,
char num[6] = "a";
// equivalent to char num[6] = {'a', '\0', '\0', '\0', '\0', '\0'};
Am I assigning a pointer to the array or copying the literal values into the array (and therefore I'm able to modify them later)?
The value will be copied, i.e. the elements of the array will be initialized by the chars of the string literal (including '\0').
String literals can be used to initialize character arrays. If an array is initialized like char str[] = "foo";, str will contain a copy of the string "foo".
Successive characters of the string literal (which includes the implicit terminating null character) initialize the elements of the array.
char num[6] = "a";
is equivalent to
char num[6] = {'a', '\0', '\0', '\0', '\0', '\0'};
Why can I assign a string literal less than the array itself?
This is allowed by the language. It is often useful to be able to add more characters to the array later, which wouldn't be possible if the existing characters filled the entire array.
Am I assigning a pointer to the array
No. You cannot assign a pointer to an array, so that is not happening.
or copying the literal values into the array
That is exactly what is happening.
and therefore I'm able to modify them later
You are able to modify the array, indeed.
Just use char num[6] = {"a"};. It works.
This kind of declaration is a special syntax sugar thing. It's equivalent to
char num[6] = {'a', 0}
The array is always modifiable. Its contents after such a declaration would be a character representing 'a', a zero (NUL terminator) and the remainder of the array will also be zeroed (zero initialization).
That is one type of declaration whcih is equivalent to
char num[6] = {'a','\0'};
You declared c-string with length of max. 5 normal chars, at the end must me \0 to end c - string.
With declaration you can use
char num[6] = "a";
then you need to assign value:
With strcpy(dest,src)
strcpy(num,"test");
Char by char
num[0]='t';
num[1]='e';
num[2]='s';
num[3]='t';
num[4]='\0';
Normally in C++, character arrays are initialized in the following way,
char example[5]="cat";
What if you initialize it with "" (just a double quotes without spaces)?
What will be the elements in the character array after initialization?
The declaration
char temp[3] = "";
is same as
char temp[3] = {0};
// `\0` ascii value is 0
remember remaining elements of half initialized array initialized with 0.
Point :char temp[3] = "" is easy to type(means writing), so its preferable.
Look even compare it with this declaration char temp[3] = {'\0'}; (it need more chars to type) Whereas in char temp[3] = ""; is simple (even no type mismatch - int/char).
It's a 3-character array initialized to three null characters.
EDIT (after comments below):
From K&R:
If there are fewer initializers for an array than the number specified, the missing elements will be zero for external, static, and automatic variables.
...
Character arrays are a special case of initialization; a string may be used instead of the braces and commas notation:
char pattern[] = "ould";
is a shorthand for the longer but equivalent
char pattern[] = { 'o', 'u', 'l', 'd', '\0' };
From a draft copy of the C++ standard, section 8.5.2, Character arrays:
"1. A char array (whether plain char, signed char, or unsigned char), char16_t array, char32_t array, or wchar_t array can be initialized by a narrow character literal, char16_t string literal, char32_t string literal, or wide string literal, respectively, or by an appropriately-typed string literal enclosed in braces. Successive characters of the value of the string literal initialize the elements of the array. [Example:
char msg[] = "Syntax error on line %s\n";
shows a character array whose members are initialized with a string-literal. Note that because ’\n’ is a single character and because a trailing ’\0’ is appended, sizeof(msg) is 25. — end example ]
...
"3. If there are fewer initializers than there are array elements, each element not explicitly initialized shall be zero-initialized (8.5)."
A blank string. The first char will be the null terminator. After an experiment, it appears the remaining characters are set to 0 (which is also null terminator).
You are setting the first element to be a null termination character. The other elements gain partial initialisation to zero: C and C++ : Partial initialization of automatic structure
I'm getting back into c++ and have the hang of pointers and whatnot, however, I was hoping I could get some help understanding why this code segment gives a bus error.
char * str1 = "Hello World";
*str1 = '5';
ERROR: Bus error :(
And more generally, I am wondering how to change the value of a single character in a cstring. Because my understanding is that *str = '5' should change the value that str points to from 'H' to '5'. So if I were to print out str it would read: "5ello World".
In an attempt to understand I wrote this code snippet too, which works as expected;
char test2[] = "Hello World";
char *testpa2 = &test2[0];
*testpa2 = '5';
This gives the desired output. So then what is the difference between testpa2 and str1? Don't they both point to the start of a series of null-terminated characters?
When you say char *str = "Hello World"; you are making a pointer to a literal string which is not changeable. It should be required to assign the literal to a const char* instead, but for historical reasons this is not the case (oops).
When you say char str[] = "Hello World;" you are making an array which is initialized to (and sized by) a string known at compile time. This is OK to modify.
Not so simple. :-)
The first one creates a pointer to the given string literal, which is allowed to be placed in read-only memory.
The second one creates an array (on the stack, usually, and thus read-write) that is initialised to the contents of the given string literal.
In the first example you try to modify a string literal, this results in undefined behavior.
As per the language standard in 2.13.4.2
Whether all string literals are
distinct (that is, are stored in
nonoverlapping objects) is
implementation-defined. The effect of
attempting to modify a string literal
is undefined.
In your second example you used string-literal initialization, defined in 8.5.2.1
A char array (whether plain char,
signed char, or unsigned char) can be
initialized by a string- literal
(optionally enclosed in braces); a
wchar_t array can be initialized by a
wide string-literal (option- ally
enclosed in braces); successive
characters of the string-literal
initialize the members of the
array.