Search code examples
cpointersmultidimensional-arrayimplicit-conversionc-strings

Two Dimensional Array of a character and string function in C


I am writing a C program which inputs string from a user sorts it alphabetical Order. I have two questions here.

When I input the strings from user in this way below no error occurs.

for(int i =0; i < 7; i++)
{
    printf("Enter the name %d\n",i+1);
    scanf("%s",&name[i][0]);
}

what does name[i][0] mean if

    char name[7][10];

Why are we setting up the 2nd index here to 0 ,isn't the 2nd dimension the maximum length of string which our arrray can handle.

My second question is For such type of array what does the string handling function takes &name[i][0] or &name[i]?

The code I have written so far gives me desired output however with lots of warning

#include<stdio.h>
#include<string.h>

int main() {
  char name[7][10];
  for (int i = 0; i < 7; i++) {
    printf("Enter the name %d\n", i + 1);
    scanf("%s", & name[i]);
    strlwr( & name[i]);
  }
  //Sort in alphabetical order
  for (int i = 0; i < 7; i++) {
    for (int j = i + 1; j < 7; j++) {
      if (strcmp( & name[i][0], & name[j][0]) > 0) {
        char temp[10];
        strcpy(temp, & name[i]);
        strcpy(name[i], & name[j]);
        strcpy(name[j], & temp);
      }
    }
  }
  printf("The names in alphabetical order is\n");
  for (int i = 0; i < 7; i++) {
    puts(name[i]);
  }
}

The warnings are:

 warning: passing argument 1 of 'strlwr' from incompatible pointer type [-Wincompatible-pointer-types]
           98 |         strlwr(&name[i]);

and similar for other functions as well.


Solution

  • names[i] is an element of the array declared like

    char name[7][10];
    

    and has the type char[10]. That is elements of this two-dimensional array are one-dimensional arrays of the type char[10].

    Used in expression array designators (with rare exceptions as for example used as operands of the sizeof operator) are converted to pointers to their first elements.

    So the expression names[i] used for example as an argument of the function scanf is converted to pointer to its first element. That is this expression is equivalent to &names[i][0].

    So instead of this call

    scanf("%s",&name[i][0])
    

    you could write

    scanf("%s", name[i] )
    

    The both expressions used as arguments have the type char *,

    This call of scanf

    scanf("%s", & name[i]);
    

    has an argument of an incorrect type. The expression &name[i] has the type char ( * )[10] while the function expects an argument of the type char * though the values of the both expressions are equal each other.

    If you have an array declared like

    char name[7][10];
    

    then the values of these expressions

    &name
    &name[0] 
    &name[0][0]
    

    are equal each other and yields the address of the first byte of the memory extent occupied by the array.

    However the types of the expressions are different. They are

    char ( * )[7][10]
    char ( * )[10]
    char *
    

    Here is a demonstrative program

    #include <stdio.h>
    
    int main(void) 
    {
        char name[7][10];
        
        printf( "&name       = %p\n", ( void * )&name );
        printf( "&name[0]    = %p\n", ( void * )&name[0] );
        printf( "&name[0][0] = %p\n", ( void * )&name[0][0] );
    
        return 0;
    }
    

    Its output might look like

    &name       = 0x7ffec1d18e40
    &name[0]    = 0x7ffec1d18e40
    &name[0][0] = 0x7ffec1d18e40
    

    By the reason described above the arguments of these calls

        strcpy(temp, & name[i]);
        strcpy(name[i], & name[j]);
    

    also have incorrect type char ( * )[10] while the function expects arguments of the type char *.

    You need to write

        strcpy(temp, name[i]);
        strcpy(name[i], name[j]);