# Array of Strings in C

A string is a 1-D array of characters, so an array of strings is a 2-D array of characters.

Just like we can create a 2-D array of `int`, `float` etc; we can also create a 2-D array of character or array of strings. Here is how we can declare a 2-D array of characters.

``````char ch_arr[3][10] = {
{'s', 'p', 'i', 'k', 'e', '\0'},
{'t', 'o', 'm','\0'},
{'j', 'e', 'r', 'r', 'y','\0'}
};
``````

It is important to end each 1-D array by the null character otherwise, it's just an array of characters. We can't use them as strings.

Declaring an array of string this way is a tedious and error-prone process that's why C provides a more compact way to it. This above initialization is equivalent to:

``````char ch_arr[3][10] = {
"spike",
"tom",
"jerry"
};
``````

The first subscript of the array i.e `3` denotes the number of strings in the array and the second subscript denotes the maximum length of the string. Recall the that in C, each character occupies `1` byte of data, so when the compiler sees the above statement it allocates `30` bytes (`3*10`) of memory.

We already know that name of an array is a pointer to the 0th element of the array. Can you guess the type of `ch_arr` ?

`ch_arr` is a pointer to an array of `10` characters or `int(*)[10]` ?

Therefore if `ch_arr` points to address `1000` then `ch_arr + 1` will point to address `1010`.

From here we can conclude that:

`ch_arr + 0` points to the 0th string or 0th 1-D array.
`ch_arr + 1` points to the 1st string or 1st 1-D array.
`ch_arr + 2` points to the 2nd string or 2nd 1-D array.

In general `ch_arr + i` points to the ith string or ith 1-D array.

We know that when we dereference a pointer to an array, we get the base address of the array. So, on dereferencing `ch_arr + i` we get the base address of the 0th 1-D array.

From this we can conclude that:

`*(ch_arr + 0) + 0` points to the 0th character of 0th 1-D array
`*(ch_arr + 0) + 1` points to the 1st character of 0th 1-D array
`*(ch_arr + 1) + 2` points to the 1st character of 0th 1-D array

Here the type of `ch_arr` is pointer to `char` or `(char*)`.

In general, we can say that:

`*(ch_arr + i) + j` points to the jth character of ith 1-D array. To get the element at jth position of ith 1-D array just dereference the expression.

``````*(*(ch_arr + i) + j)
``````

We have learned in chapter Pointers and 2-D arrays that in a 2-D array the pointer notation is equivalent to subscript notation. So the above expression can be written as follows:

``````ch_arr[i][j]
``````

The following program demonstrates how to print an array of strings.

``````#include<stdio.h>

int main()
{
int i;

char ch_arr[3][10] = {
"spike",
"tom",
"jerry"
};

printf("1st way \n\n");

for(i = 0; i < 3; i++)
{
printf("string = %s \t address = %u\n", ch_arr + i, ch_arr + i);
}

// signal to operating system program ran fine
return 0;
}
``````

Expected Output:

``````string = spike address = 2686736
string = tom address = 2686746
string = jerry address = 2686756
``````

## Some invalid operation on array of string #

``````char ch_arr[3][10] = {
{'s', 'p', 'i', 'k', 'e', '\0'},
{'t', 'o', 'm','\0'},
{'j', 'e', 'r', 'r', 'y','\0'}
};
``````

It allocates `30` bytes of memory. The compiler will do the same thing even if we don't initialize the elements of the array at the time of declaration.

We already know that the name of an array is a constant pointer so the following operations are invalid.

``````ch_arr[0] = "tyke"; // invalid
ch_arr[1] = "dragon"; // invalid
``````

Here we are trying to assign a string literal (a pointer) to a constant pointer which is obviously not possible.

To assign a new string to `ch_arr` use the following methods.

``````strcpy(ch_arr[0], "type"); // valid
scanf(ch_arr[0], "type"); // valid
``````

Let's conclude this chapter by creating another simple program.

This program asks the user to enter a username. If the username entered is one of the names in the master list then the user is allowed to calculate the factorial of a number. Otherwise, an error message is displayed.

``````#include<stdio.h>
#include<string.h>
int factorial(int );

int main()
{
int i, found = 0, n;

char master_list[5][20] = {
"tom",
"bob",
"tim",
"jim"
}, name[10];

gets(name);

for(i = 0; i < 5; i++)
{
if(strcmp(name, master_list[i]) == 0 )
{
found = 1;
break;
}
}

if(found==1)
{
printf("\nWelcome %s !\n", name);
printf("\nEnter a number to calculate the factorial: ");
scanf("%d", &n);
printf("Factorial of %d is %d", n, factorial(n));
}

else
{
printf("Error: You are not allowed to run this program.", name);
}

// signal to operating system program ran fine
return 0;
}

int factorial(int n)
{
if(n == 0)
{
return 1;
}

else
{
return n * factorial(n-1);
}
}
``````

Expected Output:

1st run:

``````Enter username: admin

Enter a number to calculate the factorial: 4
Factorial of 4 is 24
``````

2nd run:

``````Enter username: jack
Error: You are not allowed to run this program.
``````

How it works ?

The program asks the user to enter a name. After the name is entered it compares the entered name with the names in the `master_list` array using `strcmp()` function. If match is found then `strcmp()` returns `0` and the if condition `strcmp(name, master_list[i]) == 0` condition becomes true. The variable found is assigned a value of `1`, which means that the user is allowed to access the program. The program asks the user to enter a number and displays the factorial of a number.

If the name entered is not one of the names in the `master_list` array then the program exits by displaying an error message.