Const array of arrays as function argument - arrays

I don't quite understand how to correctly arrange const in order to pass a constant array of arrays to a function, for example, an array of strings:
void f (char **strings);
int main (void)
{
char strings[][2] = { "a", "b", "c" };
f (strings);
}
Could you tell me where to put const? As I understand it, there should be two const and one of them in the example above should stand before char.
There is a high probability of a duplicate, but I could not find a similar question :(

First of all, the declaration isn't ideal. char strings[][2] declares an indeterminate amount of char[2] arrays, where the amount is determined by the initializers. In most cases it makes more sense to declare an array of pointers instead, since that means that the strings pointed at do not need to have a certain fixed length.
So you could change the declaration to const char* strings[3] = { "a", "b", "c" };. Unless of course the intention is to only allow strings on 1 character and 2 null terminator, then the original code was correct. And if you need read/writeable strings then we can't use pointer notation either.
You can pass a const char* strings[3] to a function by declaring that function as
void f (const char* strings[3]);
Just like you declared the array you pass to the function.
Now as it happens, arrays when part of a function declaration "decay" into a pointer to the first element. In this case a pointer to a const char* item, written as const char**.
So you could have written void f (const char** strings); and it would have been equivalent.

I think this resource explains it nicely. In general, it depends what "depth" of const guarding you need. If you want function "f" to have read-only access on both the "outer" pointer, the pointer it points to (the "inner" pointer), and the char the "inner" pointer points to, then use
const char *const *const strings
If you want to relax the guards to make this legal:
strings = NULL;
Then use:
const char *const *strings
Relaxing further, to allow for:
strings = NULL;
*strings = NULL;
Use only one "const":
const char **strings

It is important to understand the difference between an array of arrays (for example, an array of arrays of 2 chars) and an array of pointers. As the wording suggests, their element type is totally different:
Each single element of an array of arrays, like my_arr_of_arrays below, is, well, an array! Not an address, not a pointer: Each element is a proper array, each of the same size (her: 2), a succession of a fixed number of sub-elements. The data is right there in the array object. After char my_arr_of_arrays[][2] = { "a", "b", "c", "" };, my_arr_of_arrays is a succession of characters, grouped in pairs: 'a', '\0', 'b', '\0', 'c', '\0', '\0', '\0'. The picture below illustrates that. Each element in my_arr_of_arrays has a size of 2 bytes. Each string literal is used to copy the characters in it into the corresponding array elements of my_arr_of_arrays. The data can be overwritten later, the copy is not const.
Contrast this with an array of pointers, like my_arr_of_ptrs below! Each element in such an array is, well, a pointer. The data proper is somewhere else! The actual data may have been allocated with malloc, or it is static data like the string literals in my example below. Each element — each address — has a size of 4 byte on a 32 bit architecture, or 8 byte on a 64 bit architecture. Nothing is copied from the string literals: The pointers simply point to the location in the program where the literals themselves are stored. The data is const and cannot be overwritten.
It is confusing that these completely different data structures can be initialized with the same curly-braced initializer list; it is confusing that string literals can serve as a data source for copying characters over into an array, or that their address can be taken and assigned to a pointer: Both char arr[3] = "12": and char *ptr = "12"; are valid, but for arr a copy is made and for ptr the address of the string literal itself is taken.
Your program shows that C permits you to pass an address of an array of 2 chars to a function that expects the address of a pointer; but that is wrong and leads to disaster if the function tries to dereference an "address" which is, in fact, a sequence of characters. C++ forbids this nonsensical conversion.
The following program and image may shed light on the data layout of the two different arrays.
#include <stdio.h>
void f_array_of_arrays(char(* const arr_of_arrays)[2])
{
for (int i = 0; arr_of_arrays[i][0] != 0; i++)
{
printf("string no. %d is ->%s<-\n", i, arr_of_arrays[i]);
}
const char myOtherArr[][2] = { "1", "2", "3", "4", "" };
// arr2d = myOtherArr; // <-- illegal: "const arr2d"!
arr_of_arrays[0][0] = 'x'; // <-- OK: The chars themselves are not const.
}
void f_array_of_pointers(const char** arr_of_ptrs)
{
for (int i = 0; arr_of_ptrs[i][0] != 0; i++)
{
printf("string no. %d is ->%s<-\n", i, arr_of_ptrs[i]);
}
arr_of_ptrs[1] = "87687686";
for (int i = 0; arr_of_ptrs[i][0] != 0; i++)
{
printf("after altering: string no. %d is ->%s<-\n", i, arr_of_ptrs[i]);
}
}
int main()
{
char my_arr_of_arrays[][2] = { "a", "b", "c", "\0" }; // last element has two zero bytes.
const char* my_arr_of_ptrs[] = { "111", "22", "33333", "" }; // "jagged array"
f_array_of_arrays(my_arr_of_arrays);
f_array_of_pointers(my_arr_of_ptrs);
// disaster: function thinks elements are arrays of char but
// they are addresses; does not compile as C++
// f_array_of_arrays(my_arr_of_ptrs);
// disaster: function thinks elements contain addresses and are 4 bytes,
// but they are arbitrary characters and 2 bytes long; does not compile as C++
// f_array_of_pointers(my_arr_of_arrays);
}

Related

Why do strings work, but character and int arrays do not work in a pointer array?

I understand if I add the arrays, st and st2, to give it space in the memory, and then add it to the pointer array, it shouldn't be a problem:
/* works */
int st[] = {0,31,28,31,30,31,30,31,31,30,31,30,31};
int st2[]= {0,31,29,31,30,31,30,31,31,30,31,30,31};
int *day_tab[]= {
st,
st2
};
But without first giving it space in memory, why do strings specifically work?
The code below gives an error:
int *day_tab[]= {
{0,31,28,31,30,31,30,31,31,30,31,30,31},
{0,31,29,31,30,31,30,31,31,30,31,30,31}
};
so does the code below:
char *day_tab[]= {
{'0','1','\0'},
{'0','1','\0'}
};
but the code below works
char *day_tab[]= {
"01",
"01"
};
This
int st[] = {0,31,28,31,30,31,30,31,31,30,31,30,31};
int st2[]= {0,31,29,31,30,31,30,31,31,30,31,30,31};
int *day_tab[]= {
st,
st2
};
Is three arrays: two of integers (with their own storage), and one array of two elements which are pointers to the first two arrays.
However, this is not valid:
int *day_tab[]= {
{0,31,28,31,30,31,30,31,31,30,31,30,31},
{0,31,29,31,30,31,30,31,31,30,31,30,31}
};
As before you have declared an array of pointers to integers, but pointers to what? Those braced lists are not storage locations, they cannot be pointed to.
Your final example is basically valid but dangerous:
char *day_tab[]= {
"01",
"01"
};
It is an array of two pointers to characters, and those pointers are initialized with string literals. String literals are very special in that they are actually stored somewhere, usually in read-only memory, and they can be shared (so the "01" string used twice can be stored just once). Braced lists don't have this feature in C, it's only for string literals.
The reason the final code is dangerous is that it is char* not const char*. The non-const type is accepted for reasons of backward compatibility but is not a good idea because modifying the data in a literal string is not allowed. So you're setting yourself up for a potential disaster if you actually use those pointers to write to the "01" string storage.
The following works
int *day_tab[]= {
st,
st2
};
because when you access an array, it is converted to a pointer to first element (there are few exceptions to this rule). So, when you used st and st2 array in initialisation, they will convert to pointer to first element of respective array and , after initialisation, pointer day_tab[0] will point to first element of array st and pointer day_tab[1] will point to first element of array st1.
In the code snippet
int *day_tab[]= {
{0,31,28,31,30,31,30,31,31,30,31,30,31},
{0,31,29,31,30,31,30,31,31,30,31,30,31}
};
and
char *day_tab[]= {
{'0','1','\0'},
{'0','1','\0'}
};
you are trying to initialise the pointers of array day_tab with more than one initialiser. Note that pointers are scalar types and from C11 Standard#6.7.9p11
11 The initializer for a scalar shall be a single expression, optionally enclosed in braces....
However, you can use the compound literal to initialise the pointers of day_tab int pointer array, like this:
int *day_tab[]= {
(int []){0,31,28,31,30,31,30,31,31,30,31,30,31},
(int []){0,31,29,31,30,31,30,31,31,30,31,30,31}
};
This will initialise the pointers day_tab[0] and day_tab[1] to point to the first element of respective array.
Similarly, for char pointers array, you can do
char *day_tab[]= {
(char []){'0','1','\0'},
(char []){'0','1','\0'}
};
When you do
char *day_tab[]= {
"01",
"01"
};
It works because string literals are array of characters and when it is used in the expression it will convert to pointer to type char that point to first element of array. So, this initialises the pointers day_tab[0] and day_tab[1] to point to the first element of read only string literal "01".

Best way to initialize an array of strings to pass it to a function

I need to intialize an empty array of strings with fixed size ( 3 by 100 for example), pass it to a function to fill it with data and perform things like strcpy(), strcmp(), memset() on it. After the function is terminated I need to be able to read the data from my main().
What I tried so far:
char arrayofstrings[3][100] = {0};
char (*pointer)[3][100] = &arrayofstrings;
function(pointer);
Initalizing an (empty?) array of strings and initializing a pointer on the first element.
int function (char (*pointer)[3][100])
{
strcpy((*pointer)[i], somepointertostring);
strcmp((*pointer)[i], somepointertostring)
memset((*pointer)[i], 0, strlen((*pointer)[i]));
}
Is this a good way to do it? Is there an easier way to do it? Whats up with the brackets around the pointer?
C string functions expect a buffer to be null-terminated. Your arrayofstrings allocation happens on the stack. Depending on your compiler it might be initialized to all zeros or might contain garbage.
The simplest way in your case to make sure string functions won't overrun your buffers is to set the first character of each to 0 (null)
arrayofstrings[0][0] = 0x00;
arrayofstrings[1][0] = 0x00;
arrayofstrings[2][0] = 0x00;
This will give you 3, 100-char buffers that contain a valid empty "string". Note that you can only store 99 "characters" because the last character must be 0x00 (null-terminator).
char (*pointer)[3][100] = &arrayofstrings;
This is unnecessary.
Something to keep in mind about arrays in C is that the [] index is really only there to make things easier for the human programmer. Any array definition is simply a pointer to memory. The values inside the [][]...[] indexes and the type are used by the compiler to allocate the right amount of memory on the stack and do some simple math to come up with the right memory address for the element you want to access.
char arrayofstrings[3][100];
This will allocate sizeof(char)*3*100 bytes on the stack and give you a char* called 'arrayofstrings'. There's nothing special about the char* itself. It would be the same pointer if you had char arrayofstrings[300] or char arrayofstrings[3][10][10] or even long arrayofstrings[75] (char is 1 byte, long is 4 bytes).
Because you declared it as a multidimensional array with [a][b], when you ask for arrayofstrings[x][y], the compiler will calculate ((x*b)+y)*sizeof(type) and add it to the arrayofstrings pointer to get the address of the value you want. But because it's just a pointer, you can treat it like any other pointer and pass it around or cast it to other types of pointer or do pointer math with it.
You don't need the extra level of indirection.
An array, when passed to a function, is converted to a pointer to its first member. So if you declare the function like this:
int function(char (*pointer)[100])
Or equivalently:
int function(char pointer[][100])
Or:
int function(char pointer[3][100])
You can pass the array directly to the function:
function(arrayofstrings);
Then the body could look something like this:
strcpy(pointer[0], "some string");
strcpy(pointer[1], "some other string");
strcpy(pointer[2], "yet another string");
Best way to initialize an array of strings ...
char arrayofstrings[3][100] = {0}; is fine to initialize an array of strings.
In C, initialization is done only at object definition, like above.
Later code like strcpy(), assigns data to the array.
Best way to ... pass it to a function
When the C compiler supports variable length arrays, use function(size_t n, size_t sz, char a[n][sz]).
Add error checks.
Use size_t for array sizing and indexing.
#define somepointertostring "Hello World"
int function(size_t n, size_t sz, char arrayofstrings[n][sz]) {
if (sz <= strlen(somepointertostring)) {
return 1;
}
for (size_t i = 0; i < n; i++) {
strcpy(arrayofstrings[i], somepointertostring);
if (strcmp(arrayofstrings[i], somepointertostring)) {
return 1;
}
// Drop this it see something interesting in `foo()`
memset(arrayofstrings[i], 0, strlen(arrayofstrings[i]));
}
return 0;
}
void foo(void) {
char arrayofstrings[3][100] = {0};
size_t n = sizeof arrayofstrings / sizeof arrayofstrings[0];
size_t sz = sizeof arrayofstrings[0];
if (function(n, sz, arrayofstrings)) {
puts("Fail");
} else {
puts("Success");
puts(arrayofstrings[0]);
}
}
Initalizing an (empty?) array of strings and initializing a pointer on the first element.
The type of &arrayofstrings is char (*)[3][100] i.e. pointer to an object which is a 2D array of char type with dimension 3 x 100. So, this initialisation
char (*pointer)[3][100] = &arrayofstrings;
is not initialisation of pointer with first element of arrayofstrings array but pointer will point to whole 2D array arrayofstrings. That why, when accessing the elements using pointer you need bracket around it -
`(*pointer)[0]` -> first string
`(*pointer)[1]` -> second string and so on..
Is this a good way to do it? Is there an easier way to do it?
If you want pointer to first element of array arrayofstrings then you can do
char (*p)[100] = &arrayofstrings[0];
Or
char (*p)[100] = arrayofstrings;
both &arrayofstrings[0] and arrayofstrings are equivalent1).
Pass it to a function and access the array:
function() function signature should be -
int function (char (*pointer)[100])
// if you want the function should be aware of number of rows, add a parameter for it -
// int function (char (*pointer)[100], int rows)
this is equivalent to
int function (char pointer[][100])
and call it in from main() function like this -
function (p);
In the function() function you can access array as p[0], p[1] ...:
Sample program for demonstration:
#include <stdio.h>
#include <string.h>
#define ROW 3
#define COL 100
void function (char (*p)[COL]) {
strcpy (p[0], "string one");
strcpy (p[1], "string two");
strcpy (p[2], "string three");
}
int main(void) {
char arrayofstrings[ROW][COL] = {0};
char (*pointer)[COL] = &arrayofstrings[0];
function (pointer);
for (size_t i = 0; i < ROW; ++i) {
printf ("%s\n", arrayofstrings[i]);
}
return 0;
}
When you access an array, it is converted to a pointer to first element (there are few exceptions to this rule).

How to iterate through a char ** pointer?

I have the following code
struct my_struct {
const char **enjoy;
};
const char * enjy[] = {
"Cricket", "movie", "",
"Ball", "eat", "",
};
static const struct my_struct my_struct_table[1] = {
[0] = {
.enjoy = enjy
}
};
Now I want to use that final structure and want to iterate using that.
How can I iterate using my_struct_table[0].enjoy
I want to print all the strings in the enjy variable.
Let T be any type. When working on an array of T of varying size, represented as T*, you need to specify how the end of such array is represented.
In a simpler case: for a string of characters, i.e. T = char, the end of array char* is typically represented by a null character \0. Thus, you can iterate it as:
char* ptr = myString;
for (char c = *ptr; c; c=*++ptr) {
...
}
You iterate over all characters, until you reach the one that is \0, making the expression c evaluate to false/0 and break the loop.
An alternative representation for a string is to represent the length of the string as a separate number. This is done, for example, in Pascal strings.
int size = myStringSize;
for (int idx=0; idx<size; ++idx) {
char c = myString[idx];
}
Either of the approaches can also be used when you have an array of strings (i.e. T = char*). Your options are:
You store a special non-string value in your enjoy array set to NULL at the end of the array
Or you store the total size of the enjoy array in a separate value.
You can also use both options -- this is the case, for example, with arguments given to int main(int argc, char** argv). The argc stores the number of string values in the argv, and argv[argc] is guaranteed to be NULL.
If you use the first option you would then iterate it as:
char** ptr = enjoy;
for (char* c = *ptr; c; c=*++ptr) {
...
}
and if you use the second option:
int size = enjoySize;
for (int idx=0; idx<size; ++idx) {
char* str = enjoy[idx];
}
Notice the similarity of these snippets iterating over char**, to those used for iterating over a simple char*.
Note that a value NULL stored in the enjoy array is different than storing a pointer to an empty string. The latter should not be used as a marker for the end of the array, because it can lead to hard-to-track bugs when a legitimate empty-string value is added to your enjoy array.

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.

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