unsure about initializing one dimensional char array with array of strings - c

As per my understanding array of strings can be initialized as shown below or using two dimensional array. Please tell is there any other possibility.
char *states[] = { "California", "Oregon", "Washington", "Texas" };
I have observed in U-boot source that environment variables are stored in one dimensional array as shown here:
uchar default_environment[] = {
#ifdef CONFIG_BOOTARGS
"bootargs=" CONFIG_BOOTARGS "\0"
#endif
#ifdef CONFIG_BOOTCOMMAND
"bootcmd=" CONFIG_BOOTCOMMAND "\0"
#endif
...
"\0"
};
Can you help me understand this?

A "string" is effectively nothing more than a pointer to a sequence of chars terminated by a char with the value 0 (note that the sequence must be within a single object).
char a[] = {65, 66, 67, 0, 97, 98, 99, 0, 'f', 'o', 'o', 'b', 'a', 'r', 0, 0};
/* ^ ^ ^ ^ */
In the above array we have four elements with value 0 ... so you can see that as 4 strings
// string 1
printf("%s\n", a); // prints ABC on a ASCII computer
// string 2
printf("%s\n", a + 4); // prints abc on a ASCII computer
// string 3
printf("%s\n", a + 8); // prints foobar
// string 4
printf("%s\n", a + 14); // prints empty string

As per my understanding array of strings can be initialized as shown below or using two dimensional array. Please tell is there any other possibility.
I have observed in U-boot source that environment variables are stored in one dimensional array.
If you have the implication that this default_environment is an array of strings, then it is not. This has nothing to do with array of strings initialization as in your first example.
You can try remove all #ifdef and #endif, then it'd be clear that default_environment is simply a concatenation of individual strings. For instance, "bootargs=" CONFIG_BOOTARGS "\0". Notice the \0 at the end, it will ensure that the string assigned to default_environment will not get pass the first line, given CONFIG_BOOTARGS is defined.
uchar default_environment[] = {
#ifdef CONFIG_BOOTARGS
"bootargs=" CONFIG_BOOTARGS "\0"
#endif
#ifdef CONFIG_BOOTCOMMAND
"bootcmd=" CONFIG_BOOTCOMMAND "\0"
#endif
...
"\0"
};

They are not creating an array of strings there, such as your char *states[], it's a single string that is being created (as a char[]). The individual 'elements' inside the string are denoted by zero-termination.
To translate your example
char *states[] = { "California", "Oregon", "Washington", "Texas" };
to their notation would be
char states[] = { "California" "\0" "Oregon" "\0" "Washington" "\0" "Texas" "\0" "\0" };
which is the same as
char states[] = { "California\0Oregon\0Washington\0Texas\0\0" };
You can use these by getting a pointer to the start of each zero-terminated block and then the string functions, such as strlen will read until they see the next '\0' character.
As for the why of it, #M.M.'s comment gives some good indication.

If we simplify the question to what is the difference between initialising a char *foo versus a char foo[100] it might help. Check out the following code:
char buffer1[100] = "this is a test";
char *buffer2 = "this is a test";
int main(void)
{
printf("buffer1 = %s\n", buffer1);
buffer1[0] = 'T';
printf("buffer1 = %s\n", buffer1);
printf("buffer2 = %s\n", buffer2);
buffer2[0] = 'T';
printf("buffer2 = %s\n", buffer2); // this will fail
}
In the first case (buffer1) we initialise a character array with a string. The compiler will allocate 100 bytes for the array, and initialise the contents to "this is a test\0\0\0\0\0\0\0\0\0...". This array is modifiable like any other heap memory.
In the second case, we didn't allocate any memory for an array. All we asked the compiler to do is set aside enough memory for a pointer (4 or 8 bytes typically), then initialise that to point to a string stored somewhere else. Typically the compiler will either generate a separate code segment for the string, or else just store it inline with the code. In either case this string is read-only. So on the final line where I attempted to write to it, it caused a seg-fault.
That is the difference between initialising an array and a pointer.

The common technique is to use an array of pointers (note: this is different from a 2D array!) as:
char *states[] = { "California", "Oregon", "Washington", "Texas" };
That way, states is an array of 4 char pointer, and you use it simply printf("State %s", states[i]);
For completeness, a 2D array would be char states[11][5] with all rows having same length which is pretty uncommon, and harder to initialize.
But some special use cases or API(*) require (or return) a single char array where strings are (normally) terminated with \0, the array itself being terminated by an empty element, that it two consecutive \0. This representation allows a single allocation bloc for the whole array, when the common array of pointers has the array of pointers in one place and the strings themselves in another place. By the way, it is easy to rebuild an array of pointers from that 1D characater arrays with \0 as separators, and it is generally done to be able to easily use the strings.
The last interesting point of the uchar default_environment[] technique is that it is a nice serialization: you can directly save it to a file and load it back. And as I have already said, the common usage is then to build an array of pointers to access easily to the individual strings.
(*) For example, the WinAPI functions GetPrivateProfileSection and WritePrivateProfileSection use such a representation to set or get a list of key=value strings in one single call.

Yes, you can create and initialized array of string or hierarchy of arrays using pointers. Describing it in details in case someone needs it.
A single char
1. char states;
Pointer to array of chars.
2. char *states = (char *) malloc(5 * sizeof(char)):
Above statement is equivalent to char states[5];
Now its up to you if you initialize it with strcpy() like
strcpy(states, "abcd");
or use direct values like this.
states[0] = 'a';
states[1] = 'b';
states[2] = 'c';
states[3] = 'd';
states[4] = '/0';
Although if you store any other char on index 4 it will work but it would be better to end this using null character '\0' .
Pointer to array of pointers or pointer to a matrix of chars
3. char ** states = (char **) malloc(5 * sizeof(char *));
It is an array of pointers i.e. each element is a pointer, which can point to or in other word hold a string etc. like
states[0] = malloc ( sizeof(char) * number );
states[1] = malloc ( sizeof(char) * number );
states[2] = malloc ( sizeof(char) * number );
states[3] = malloc ( sizeof(char) * number );
states[4] = malloc ( sizeof(char) * number );
Above statement is equivalent to char states[5][number];
Again its up to you how you initialize these pointers to strings i.e.
strcpy( states[0] , "hello");
strcpy ( states[1], "World!!");
states[2][0] = 'a';
states[2][1] = 'b';
states[2][2] = 'c';
states[2][3] = 'd';
states[2][4] = '\0';
Pointer to matrix of pointers or pointer to 3D chars
char *** states = (char ***) malloc(5 * sizeof(char**));
and so on.
Actually each of these possibilities reaches somehow to pointers.

Related

Create an array of strings without allocating each string

I am trying to figure out how to create an array of strings (considering I know the max length of each string).
char** strings = NULL;
strings = malloc (5*sizeof(char*));
Once I did that, how can I just fill the array without the need to allocate each string separately? Lets say I know the max length of a string is 20, how to I set it?
After the allocation of the string I wish to do the following:
strings[0] = "string";
strings[1] = "another string";
etc.
Thanks
You can declare an array of pointers to char and then assign string literals to those pointers
char *strings[5];
strings[0] = "string";
strings[1] = "another string";
/* ... */
But note that, these strings will be immutable.
You can also use an array of char arrays
char strings[5][20]; // As you know max length of string is 20
strcpy(strings[0], "string");
strcpy(strings[1], "another string");
/* ... */
One of the advantage of latter is strings will be mutable.
If you know the maximum size of each line, and if you know the maximum number of lines, you could simply define a two-dimensional array of chars, i.e. char arr[5][20+1]. Then you will have reserved space for up to 5 lines, each comprising up to 20 characters (+ null char).
And you could also define a type alias representing such a line (if you like):
#define MaxLineLength 20
typedef char Line[MaxLineLength+1];
int main() {
Line input = { 0 };
scanf("%20s", input);
Line a[5] = { 0 };
strcpy(a[0], input);
strcpy(a[1], "string1");
return 0;
}

How to copy a char array in C?

In C, I have two char arrays:
char array1[18] = "abcdefg";
char array2[18];
How to copy the value of array1 to array2 ? Can I just do this: array2 = array1?
You can't directly do array2 = array1, because in this case you manipulate the addresses of the arrays (char *) and not of their inner values (char).
What you, conceptually, want is to do is iterate through all the chars of your source (array1) and copy them to the destination (array2). There are several ways to do this. For example you could write a simple for loop, or use memcpy.
That being said, the recommended way for strings is to use strncpy. It prevents common errors resulting in, for example, buffer overflows (which is especially dangerous if array1 is filled from user input: keyboard, network, etc). Like so:
// Will copy 18 characters from array1 to array2
strncpy(array2, array1, 18);
As #Prof. Falken mentioned in a comment, strncpy can be evil. Make sure your target buffer is big enough to contain the source buffer (including the \0 at the end of the string).
If your arrays are not string arrays, use:
memcpy(array2, array1, sizeof(array2));
If you want to guard against non-terminated strings, which can cause all sorts of problems, copy your string like this:
char array1[18] = {"abcdefg"};
char array2[18];
size_t destination_size = sizeof (array2);
strncpy(array2, array1, destination_size);
array2[destination_size - 1] = '\0';
That last line is actually important, because strncpy() does not always null terminate strings. (If the destination buffer is too small to contain the whole source string, sntrcpy() will not null terminate the destination string.)
The manpage for strncpy() even states "Warning: If there is no null byte among the first n bytes of src, the string placed in dest will not be null-terminated."
The reason strncpy() behaves this somewhat odd way, is because it was not actually originally intended as a safe way to copy strings.
Another way is to use snprintf() as a safe replacement for strcpy():
snprintf(array2, destination_size, "%s", array1);
(Thanks jxh for the tip.)
As others have noted, strings are copied with strcpy() or its variants. In certain cases, you could use snprintf() as well.
You can only assign arrays the way you want as part of a structure assignment:
typedef struct { char a[18]; } array;
array array1 = { "abcdefg" };
array array2;
array2 = array1;
If your arrays are passed to a function, it will appear that you are allowed to assign them, but this is just an accident of the semantics. In C, an array will decay to a pointer type with the value of the address of the first member of the array, and this pointer is what gets passed. So, your array parameter in your function is really just a pointer. The assignment is just a pointer assignment:
void foo (char x[10], char y[10]) {
x = y; /* pointer assignment! */
puts(x);
}
The array itself remains unchanged after returning from the function.
This "decay to pointer value" semantic for arrays is the reason that the assignment doesn't work. The l-value has the array type, but the r-value is the decayed pointer type, so the assignment is between incompatible types.
char array1[18] = "abcdefg";
char array2[18];
array2 = array1; /* fails because array1 becomes a pointer type,
but array2 is still an array type */
As to why the "decay to pointer value" semantic was introduced, this was to achieve a source code compatibility with the predecessor of C. You can read The Development of the C Language for details.
You cannot assign arrays, the names are constants that cannot be changed.
You can copy the contents, with:
strcpy(array2, array1);
assuming the source is a valid string and that the destination is large enough, as in your example.
it should look like this:
void cstringcpy(char *src, char * dest)
{
while (*src) {
*(dest++) = *(src++);
}
*dest = '\0';
}
.....
char src[6] = "Hello";
char dest[6];
cstringcpy(src, dest);
I recommend to use memcpy() for copying data.
Also if we assign a buffer to another as array2 = array1 , both array have same memory and any change in the arrary1 deflects in array2 too. But we use memcpy, both buffer have different array. I recommend memcpy() because strcpy and related function do not copy NULL character.
array2 = array1;
is not supported in c. You have to use functions like strcpy() to do it.
c functions below only ... c++ you have to do char array then use a string copy then user the string tokenizor functions... c++ made it a-lot harder to do anythng
#include <iostream>
#include <fstream>
#include <cstring>
#define TRUE 1
#define FALSE 0
typedef int Bool;
using namespace std;
Bool PalTrueFalse(char str[]);
int main(void)
{
char string[1000], ch;
int i = 0;
cout<<"Enter a message: ";
while((ch = getchar()) != '\n') //grab users input string untill
{ //Enter is pressed
if (!isspace(ch) && !ispunct(ch)) //Cstring functions checking for
{ //spaces and punctuations of all kinds
string[i] = tolower(ch);
i++;
}
}
string[i] = '\0'; //hitting null deliminator once users input
cout<<"Your string: "<<string<<endl;
if(PalTrueFalse(string)) //the string[i] user input is passed after
//being cleaned into the null function.
cout<<"is a "<<"Palindrome\n"<<endl;
else
cout<<"Not a palindrome\n"<<endl;
return 0;
}
Bool PalTrueFalse(char str[])
{
int left = 0;
int right = strlen(str)-1;
while (left<right)
{
if(str[left] != str[right]) //comparing most outer values of string
return FALSE; //to inner values.
left++;
right--;
}
return TRUE;
}
Well, techincally you can…
typedef struct { char xx[18]; } arr_wrap;
char array1[18] = "abcdefg";
char array2[18];
*((arr_wrap *) array2) = *((arr_wrap *) array1);
printf("%s\n", array2); /* "abcdefg" */
but it will not look very beautiful.
…Unless you use the C preprocessor…
#define CC_MEMCPY(DESTARR, SRCARR, ARRSIZE) \
{ struct _tmparrwrap_ { char xx[ARRSIZE]; }; *((struct _tmparrwrap_ *) DESTARR) = *((struct _tmparrwrap_ *) SRCARR); }
You can then do:
char array1[18] = "abcdefg";
char array2[18];
CC_MEMCPY(array2, array1, sizeof(array1));
printf("%s\n", array2); /* "abcdefg" */
And it will work with any data type, not just char:
int numbers1[3] = { 1, 2, 3 };
int numbers2[3];
CC_MEMCPY(numbers2, numbers1, sizeof(numbers1));
printf("%d - %d - %d\n", numbers2[0], numbers2[1], numbers2[2]); /* "abcdefg" */
(Yes, the code above is granted to work always and it's portable)
for integer types
#include <string.h>
int array1[10] = {0,1,2,3,4,5,6,7,8,9};
int array2[10];
memcpy(array2,array1,sizeof(array1)); // memcpy("destination","source","size")
You cannot assign arrays to copy them. How you can copy the contents of one into another depends on multiple factors:
For char arrays, if you know the source array is null terminated and destination array is large enough for the string in the source array, including the null terminator, use strcpy():
#include <string.h>
char array1[18] = "abcdefg";
char array2[18];
...
strcpy(array2, array1);
If you do not know if the destination array is large enough, but the source is a C string, and you want the destination to be a proper C string, use snprinf():
#include <stdio.h>
char array1[] = "a longer string that might not fit";
char array2[18];
...
snprintf(array2, sizeof array2, "%s", array1);
If the source array is not necessarily null terminated, but you know both arrays have the same size, you can use memcpy:
#include <string.h>
char array1[28] = "a non null terminated string";
char array2[28];
...
memcpy(array2, array1, sizeof array2);
None of the above was working for me..
this works perfectly
name here is char *name which is passed via the function
get length of char *name using strlen(name)
storing it in a const variable is important
create same length size char array
copy name 's content to temp using strcpy(temp, name);
use however you want, if you want original content back. strcpy(name, temp); copy temp back to name and voila works perfectly
const int size = strlen(name);
char temp[size];
cout << size << endl;
strcpy(temp, name);
You can't copy directly by writing array2 = array1.
If you want to copy it manually, iterate over array1 and copy item by item as follows -
int i;
for(i=0;array1[i]!='\0';i++){
array2[i] = array1[i];
}
array2[i]='\0'; //put the string terminator too
If you are ok to use string library, you can do it as follows -
strncpy ( array2, array1, sizeof(array2) );

What does that mean in c? char *array[]= { "**", "**", "**" };

In some code that I read, there was an initializing statement like this
char *array[]= { "something1", "something2", "something3" };
What does this mean, and what does that pointer actually point to?
How is that allocated in memory, and how can I access every element and every character of an element in that array ?
--- Edited ---
and please what is the difference in this example between
char array[3];
and
char *array[3];
--- Edited ---
what that means ?
It's initializing an array of strings (char *) with three values (three pointers to null-terminating strings)
and what that pointer points to ?
It should point to the first element in the char* array
how is that allocated in memory ?
It will allocate enough memory to store the three strings followed by null-terminators, as well as the three pointers to those strings:
array --> pointer to three sequential memory addresses
array[0] --> something1{\0}
array[1] --> something2{\0}
array[2] --> something3{\0}
Note that the strings may not necessarily be in sequential memory
and how can I access every element
if by "element" you mean the string, you can loop though the pointers:
for(int i=0; i<3; i++)
{
char* element = array[i];
}
and every character of an element in that array
well, you could access the chars using array syntax (element[i]) but I would recommend using the C string functions for safety (so you don't have to worry about accessing memory outside the range of the string)
This is a way to initialize an array at the same time that you create it.
This code
char *array[]= { "a", "b", "c" };
will have the same result as this code.
char *array[3];
array[0] = "a";
array[1] = "b";
array[2] = "c";
Here is a good source for more information.
http://www.iu.hio.no/~mark/CTutorial/CTutorial.html#Strings
EDIT:
char array[3]; is an array of 3 char.
char *array[3]; is an array of 3 pointers to char.
char * in C is a string.
array is the name of the variable being declared.
[] indicates that it is an array.
{ "something1", "something2", "something3" } is initializing the contents of the array.
Accessing elements is done like so:
array[0] gives the 1st element - "something1".
array[1] gives the 2nd element - "something2".
etc.
Note:
As was pointed out in the comments, char * isn't technically a string.
It's a pointer to a char. You can visualize a string in memory like so:
<-------------------------->
..134|135|136|137|138|139|..
<-------------------------->
'H'|'e'|'l'|'l'|'o'|'\0'
<-------------------------->
This block of memory (locations 134-139) is holding the string of characters.
For example:
array[0] actually returns a pointer to the first character in "something1".
You use the fact that the characters are sequentially in memory to access the rest of the string in various ways:
/* ch points to the 's' */
char* ch = array[0];
/* ch2 points to the 'e' */
char* ch2 = ch + 3;
/* ch3 == 'e' */
char ch3 = *ch2;
/* ch4 == 'e' */
char ch4 = *(ch + 3);
/* ch5 == 'e' */
char ch5 = ch[3];
This defines a array of char pointers (aka. "c strings").
For accessing the content you could do:
for (int i=0; i<sizeof(array)/sizeof(char*); i++) {
printf("%s", array[i]);
}
It declares array as an array of 3 pointers to char, with its 3 elements initialized to pointers to the respective strings. The memory is allocated for the array itself (3 pointers) and for the strings. The strings memory is allocated statically. The array's memory is allocated either statically (if the declaration is outside of all functions) or dynamically (typically, on the execution stack of the CPU) if the declaration is inside a function.

Printing an array of characters

I have an array of characters declared as:
char *array[size];
When I perform a
printf("%s", array);
it gives me some garbage characters, why it is so?
http://www.cplusplus.com/reference/clibrary/cstdio/printf/
This url indicates printf takes in the format of: `int printf ( const char * format, ... );
#include <stdio.h>
#include <string.h>
#define size 20
#define buff 100
char line[buff];
int main ()
{
char *array[100];
char *sep = " \t\n";
fgets(line, buff, stdin);
int i;
array[0] = strtok(line, sep);
for (i = 1; i < size; i++) {
array[i] = strtok(NULL, sep);
if (array[i] == NULL)
break;
}
return 0;
}
You declare an array of characters like so:
char foo[size];
You seem to have it mixed up with char *, which is a pointer to a character. You could say
char *bar = foo;
which would make bar point to the contents of foo. (Or, actually, to the first character of foo.)
To then print the contents of the array, you can do one of the following:
// either print directly from foo:
printf("%s", foo);
// or print through bar:
printf("%s", bar);
Note, however, that C performs no initialization of the contents of variables, so unless you specifically set the contents to something, you'll get garbage. In addition, if that garbage doesn't happen to contain a \0; that is, a char with value 0, it will keep on outputting past the end of the array.
Your array is not initialized, and also you have an array of pointers, instead of an array of char's. It should be char* array = (char*)malloc(sizeof(char)*size);, if you want an array of char's. Now you have a pointer to the first element of the array.
Why are we making such a simple thing sound so difficult?
char array[SIZE];
... /* initialize array */
puts(array); /* prints the string/char array and a new line */
/* OR */
printf("%s", array); /* prints the string as is, without a new line */
The char in array after the end of what you want to be your string (ie. if you want your string to read "Hello" that would be the next char after the 'o') must be the terminating NUL character '\0'. If you use a C function to read input that would automatically be appended to the end of your buffer. You would only need to worry about doing it manually if you were individually writing characters to your buffer or something for some reason.
EDIT: As with pmg's comment, the '\0' goes wherever you want the string to end, so if you wanted to shorten your string you could just move it up closer to the front, or to have an empty string you just have array[0] = '\0';. Doing so can also be used to tokenise smaller strings inside a single buffer, just as strtok does. ie. "Part1\0Part2\0Part3\0". But I think this is getting away from the scope of the question.
ie. you wanted to store the first 3 chars of the alphabet as a string (don't know why anyone would do it this way but it's just an example):
char array[4];
array[0] = 'a';
array[1] = 'b';
array[2] = 'c';
array[3] = '\0';
printf("%s\n", array);
If you have something like char array[] = "Hello"; the '\0' is automatically added for you.
char *array[size];
array is not a char * with that, it's more like a char ** (pointer to an array of chars, with is similar to pointer to pointer to char).
If all you need is a C string, either:
char array[size];
and make sure you 0-terminate it properly, or
char *array;
and make sure you properly allocate and free storage for it (and 0-terminate it too).

How do I create an array of strings in C?

I am trying to create an array of strings in C. If I use this code:
char (*a[2])[14];
a[0]="blah";
a[1]="hmm";
gcc gives me "warning: assignment from incompatible pointer type". What is the correct way to do this?
edit: I am curious why this should give a compiler warning since if I do printf(a[1]);, it correctly prints "hmm".
If you don't want to change the strings, then you could simply do
const char *a[2];
a[0] = "blah";
a[1] = "hmm";
When you do it like this you will allocate an array of two pointers to const char. These pointers will then be set to the addresses of the static strings "blah" and "hmm".
If you do want to be able to change the actual string content, the you have to do something like
char a[2][14];
strcpy(a[0], "blah");
strcpy(a[1], "hmm");
This will allocate two consecutive arrays of 14 chars each, after which the content of the static strings will be copied into them.
There are several ways to create an array of strings in C. If all the strings are going to be the same length (or at least have the same maximum length), you simply declare a 2-d array of char and assign as necessary:
char strs[NUMBER_OF_STRINGS][STRING_LENGTH+1];
...
strcpy(strs[0], aString); // where aString is either an array or pointer to char
strcpy(strs[1], "foo");
You can add a list of initializers as well:
char strs[NUMBER_OF_STRINGS][STRING_LENGTH+1] = {"foo", "bar", "bletch", ...};
This assumes the size and number of strings in the initializer match up with your array dimensions. In this case, the contents of each string literal (which is itself a zero-terminated array of char) are copied to the memory allocated to strs. The problem with this approach is the possibility of internal fragmentation; if you have 99 strings that are 5 characters or less, but 1 string that's 20 characters long, 99 strings are going to have at least 15 unused characters; that's a waste of space.
Instead of using a 2-d array of char, you can store a 1-d array of pointers to char:
char *strs[NUMBER_OF_STRINGS];
Note that in this case, you've only allocated memory to hold the pointers to the strings; the memory for the strings themselves must be allocated elsewhere (either as static arrays or by using malloc() or calloc()). You can use the initializer list like the earlier example:
char *strs[NUMBER_OF_STRINGS] = {"foo", "bar", "bletch", ...};
Instead of copying the contents of the string constants, you're simply storing the pointers to them. Note that string constants may not be writable; you can reassign the pointer, like so:
strs[i] = "bar";
strs[i] = "foo";
But you may not be able to change the string's contents; i.e.,
strs[i] = "bar";
strcpy(strs[i], "foo");
may not be allowed.
You can use malloc() to dynamically allocate the buffer for each string and copy to that buffer:
strs[i] = malloc(strlen("foo") + 1);
strcpy(strs[i], "foo");
BTW,
char (*a[2])[14];
Declares a as a 2-element array of pointers to 14-element arrays of char.
Ack! Constant strings:
const char *strings[] = {"one","two","three"};
If I remember correctly.
Oh, and you want to use strcpy for assignment, not the = operator. strcpy_s is safer, but it's neither in C89 nor in C99 standards.
char arr[MAX_NUMBER_STRINGS][MAX_STRING_SIZE];
strcpy(arr[0], "blah");
Update: Thomas says strlcpy is the way to go.
Here are some of your options:
char a1[][14] = { "blah", "hmm" };
char* a2[] = { "blah", "hmm" };
char (*a3[])[] = { &"blah", &"hmm" }; // only since you brought up the syntax -
printf(a1[0]); // prints blah
printf(a2[0]); // prints blah
printf(*a3[0]); // prints blah
The advantage of a2 is that you can then do the following with string literals
a2[0] = "hmm";
a2[1] = "blah";
And for a3 you may do the following:
a3[0] = &"hmm";
a3[1] = &"blah";
For a1 you will have to use strcpy() (better yet strncpy()) even when assigning string literals. The reason is that a2, and a3 are arrays of pointers and you can make their elements (i.e. pointers) point to any storage, whereas a1 is an array of 'array of chars' and so each element is an array that "owns" its own storage (which means it gets destroyed when it goes out of scope) - you can only copy stuff into its storage.
This also brings us to the disadvantage of using a2 and a3 - since they point to static storage (where string literals are stored) the contents of which cannot be reliably changed (viz. undefined behavior), if you want to assign non-string literals to the elements of a2 or a3 - you will first have to dynamically allocate enough memory and then have their elements point to this memory, and then copy the characters into it - and then you have to be sure to deallocate the memory when done.
Bah - I miss C++ already ;)
p.s. Let me know if you need examples.
If you don't want to keep track of number of strings in array and want to iterate over them, just add NULL string in the end:
char *strings[]={ "one", "two", "three", NULL };
int i=0;
while(strings[i]) {
printf("%s\n", strings[i]);
//do something
i++;
};
Or you can declare a struct type, that contains a character arry(1 string), them create an array of the structs and thus a multi-element array
typedef struct name
{
char name[100]; // 100 character array
}name;
main()
{
name yourString[10]; // 10 strings
printf("Enter something\n:);
scanf("%s",yourString[0].name);
scanf("%s",yourString[1].name);
// maybe put a for loop and a few print ststements to simplify code
// this is just for example
}
One of the advantages of this over any other method is that this allows you to scan directly into the string without having to use strcpy;
If the strings are static, you're best off with:
const char *my_array[] = {"eenie","meenie","miney"};
While not part of basic ANSI C, chances are your environment supports the syntax. These strings are immutable (read-only), and thus in many environments use less overhead than dynamically building a string array.
For example in small micro-controller projects, this syntax uses program memory rather than (usually) more precious ram memory. AVR-C is an example environment supporting this syntax, but so do most of the other ones.
In ANSI C:
char* strings[3];
strings[0] = "foo";
strings[1] = "bar";
strings[2] = "baz";
The string literals are const char *s.
And your use of parenthesis is odd. You probably mean
const char *a[2] = {"blah", "hmm"};
which declares an array of two pointers to constant characters, and initializes them to point at two hardcoded string constants.
Your code is creating an array of function pointers. Try
char* a[size];
or
char a[size1][size2];
instead.
See wikibooks to arrays and pointers
hello you can try this bellow :
char arr[nb_of_string][max_string_length];
strcpy(arr[0], "word");
a nice example of using, array of strings in c if you want it
#include <stdio.h>
#include <string.h>
int main(int argc, char *argv[]){
int i, j, k;
// to set you array
//const arr[nb_of_string][max_string_length]
char array[3][100];
char temp[100];
char word[100];
for (i = 0; i < 3; i++){
printf("type word %d : ",i+1);
scanf("%s", word);
strcpy(array[i], word);
}
for (k=0; k<3-1; k++){
for (i=0; i<3-1; i++)
{
for (j=0; j<strlen(array[i]); j++)
{
// if a letter ascii code is bigger we swap values
if (array[i][j] > array[i+1][j])
{
strcpy(temp, array[i+1]);
strcpy(array[i+1], array[i]);
strcpy(array[i], temp);
j = 999;
}
// if a letter ascii code is smaller we stop
if (array[i][j] < array[i+1][j])
{
j = 999;
}
}
}
}
for (i=0; i<3; i++)
{
printf("%s\n",array[i]);
}
return 0;
}
char name[10][10]
int i,j,n;//here "n" is number of enteries
printf("\nEnter size of array = ");
scanf("%d",&n);
for(i=0;i<n;i++)
{
for(j=0;j<1;j++)
{
printf("\nEnter name = ");
scanf("%s",&name[i]);
}
}
//printing the data
for(i=0;i<n;i++)
{
for(j=0;j<1;j++)
{
printf("%d\t|\t%s\t|\t%s",rollno[i][j],name[i],sex[i]);
}
printf("\n");
}
Here try this!!!
I was missing somehow more dynamic array of strings, where amount of strings could be varied depending on run-time selection, but otherwise strings should be fixed.
I've ended up of coding code snippet like this:
#define INIT_STRING_ARRAY(...) \
{ \
char* args[] = __VA_ARGS__; \
ev = args; \
count = _countof(args); \
}
void InitEnumIfAny(String& key, CMFCPropertyGridProperty* item)
{
USES_CONVERSION;
char** ev = nullptr;
int count = 0;
if( key.Compare("horizontal_alignment") )
INIT_STRING_ARRAY( { "top", "bottom" } )
if (key.Compare("boolean"))
INIT_STRING_ARRAY( { "yes", "no" } )
if( ev == nullptr )
return;
for( int i = 0; i < count; i++)
item->AddOption(A2T(ev[i]));
item->AllowEdit(FALSE);
}
char** ev picks up pointer to array strings, and count picks up amount of strings using _countof function. (Similar to sizeof(arr) / sizeof(arr[0])).
And there is extra Ansi to unicode conversion using A2T macro, but that might be optional for your case.
Each element is a pointer to its first character
const char *a[2] = {"blah", "hmm"};
A good way is to define a string your self.
#include <stdio.h>
typedef char string[]
int main() {
string test = "string";
return 0;
}
It's really that simple.

Resources