How come this works:
Char name[20] = "Mary";
But this doesn't.
Char name[20];
Name[20] = "Mary";
Am I correct in that the above fails because I'm telling it to put "Mary" in the name[20] element? Is that how it's interpreted?
Is there a way to initialize char name[20] array separately from the declaration without using srtcpy()? Just wondering
Thanks
C char array initialization: what happens if there are less characters in the string literal than the array size? - Stack Overflow
c - Is initializing a char[] with a string literal bad practice? - Software Engineering Stack Exchange
How to initialize a char array with double quotes (not printable escape characters) in C++
Initializing Char Arrays - C++ Forum
Videos
The first declaration:
char buf[10] = "";is equivalent to
char buf[10] = {0, 0, 0, 0, 0, 0, 0, 0, 0, 0};The second declaration:
char buf[10] = " ";is equivalent to
char buf[10] = {' ', 0, 0, 0, 0, 0, 0, 0, 0, 0};The third declaration:
char buf[10] = "a";is equivalent to
char buf[10] = {'a', 0, 0, 0, 0, 0, 0, 0, 0, 0};
As you can see, no random content: if there are fewer initializers, the remaining of the array is initialized with 0. This the case even if the array is declared inside a function.
These are equivalent
char buf[10] = ""; char buf[10] = {0}; char buf[10] = {0, 0, 0, 0, 0, 0, 0, 0, 0, 0};These are equivalent
char buf[10] = " "; char buf[10] = {' '}; char buf[10] = {' ', 0, 0, 0, 0, 0, 0, 0, 0, 0};These are equivalent
char buf[10] = "a"; char buf[10] = {'a'}; char buf[10] = {'a', 0, 0, 0, 0, 0, 0, 0, 0, 0};
It's anyways bad practice to initialie a char array with a string literal.
The author of that comment never really justifies it, and I find the statement puzzling.
In C (and you've tagged this as C), that's pretty much the only way to initialize an array of char with a string value (initialization is different from assignment). You can write either
char string[] = "october";
or
char string[8] = "october";
or
char string[MAX_MONTH_LENGTH] = "october";
In the first case, the size of the array is taken from the size of the initializer. String literals are stored as arrays of char with a terminating 0 byte, so the size of the array is 8 ('o', 'c', 't', 'o', 'b', 'e', 'r', 0). In the second two cases, the size of the array is specified as part of the declaration (8 and MAX_MONTH_LENGTH, whatever that happens to be).
What you cannot do is write something like
char string[];
string = "october";
or
char string[8];
string = "october";
etc. In the first case, the declaration of string is incomplete because no array size has been specified and there's no initializer to take the size from. In both cases, the = won't work because a) an array expression such as string may not be the target of an assignment and b) the = operator isn't defined to copy the contents of one array to another anyway.
By that same token, you can't write
char string[] = foo;
where foo is another array of char. This form of initialization will only work with string literals.
EDIT
I should amend this to say that you can also initialize arrays to hold a string with an array-style initializer, like
char string[] = {'o', 'c', 't', 'o', 'b', 'e', 'r', 0};
or
char string[] = {111, 99, 116, 111, 98, 101, 114, 0}; // assumes ASCII
but it's easier on the eyes to use string literals.
EDIT2
In order to assign the contents of an array outside of a declaration, you would need to use either strcpy/strncpy (for 0-terminated strings) or memcpy (for any other type of array):
if (sizeof string > strlen("october"))
strcpy(string, "october");
or
strncpy(string, "october", sizeof string); // only copies as many characters as will
// fit in the target buffer; 0 terminator
// may not be copied, but the buffer is
// uselessly completely zeroed if the
// string is shorter!
The only problem I recall is assigning string literal to char *:
char var1[] = "september";
var1[0] = 'S'; // Ok - 10 element char array allocated on stack
char const *var2 = "september";
var2[0] = 'S'; // Compile time error - pointer to constant string
char *var3 = "september";
var3[0] = 'S'; // Modifying some memory - which may result in modifying... something or crash
For example take this program:
#include <stdio.h>
int main() {
char *var1 = "september";
char *var2 = "september";
var1[0] = 'S';
printf("%s\n", var2);
}
This on my platform (Linux) crashes as it tries to write to page marked as read-only. On other platforms it might print 'September' etc.
That said - initialization by literal makes the specific amount of reservation so this won't work:
char buf[] = "May";
strncpy(buf, "September", sizeof(buf)); // Result "Sep"
But this will
char buf[32] = "May";
strncpy(buf, "September", sizeof(buf));
As last remark - I wouldn't use strcpy at all:
char buf[8];
strcpy(buf, "very long string very long string"); // Oops. We overwrite some random memory
While some compilers can change it into safe call strncpy is much safer:
char buf[1024];
strncpy(buf, something_else, sizeof(buf)); // Copies at most sizeof(buf) chars so there is no possibility of buffer overrun. Please note that sizeof(buf) works for arrays but NOT pointers.
buf[sizeof(buf) - 1] = '\0';
You can't - in C. In C initializing of global and local static variables are designed such that the compiler can put the values statically into the executable. It can't handle non-constant expressions as initializers. And only in C99, you can use non-constant expression in aggregate initializers - not so in C89!
In your case, since your array is an array containing characters, each element has to be an arithmetic constant expression. Look what it says about those
An arithmetic constant expression shall have arithmetic type and shall only have operands that are integer constants, floating constants, enumeration constants, character constants, and sizeof expressions.
Surely this is not satisfied by your initializer, which uses an operand of pointer type. Surely, the other way is to initialize your array using a string literal, as it explains too
All the expressions in an initializer for an object that has static storage duration shall be constant expressions or string literals.
All quotes are taken out of the C99 TC3 committee draft. So to conclude, what you want to do - using non-constant expression - can't be done with C. You have several options:
- Write your stuff multiple times - one time reversed, and the other time not reversed.
- Change the language - C++ can do that all.
- If you really want to do that stuff, use an array of
char const*instead
Here is what i mean by the last option
char const c[] = "ABCD";
char const *f[] = { &c[0], &c[1], &c[2], &c[3] };
char const *g[] = { &c[3], &c[2], &c[1], &c[0] };
That works fine, as an address constant expression is used to initialize the pointers
An address constant is a null pointer, a pointer to an lvalue designating an object of static storage duration, or a pointer to a function designator; it shall be created explicitly using the unary & operator or an integer constant cast to pointer type, or implicitly by the use of an expression of array or function type. The array-subscript [] and member-access . and -> operators, the address & and indirection * unary operators, and pointer casts may be used in the creation of an address constant, but the value of an object shall not be accessed by use of these operators.
You may have luck tweaking your compiler options - another quote:
An implementation may accept other forms of constant expressions.
Simply
const char S[] = "ABCD";
should work.
What's your compiler?