-11

I'm working on a homework that has to do with strings. Here's the code


int main(){
    char a[50][50];
    int n;
    printf("Enter the value of n\n");
    scanf("%d",&n);
    printf("Enter %d names\n",n);
    fflush(stdin);
    for(int i=0; i<n; i++){
        gets(a[i]);
    }

I tried to change the char a[50][50] into char a[50] but the entire program didn't run, came along with this error message: "Invalid conversion from 'char' to '*char' I don't really understand how this works.

Kami Hoang
  • 97
  • 1
  • 10
  • 9
    [Beginner's Tutorial](https://beginnersbook.com/2014/01/2d-arrays-in-c-example/) or try any other C book of your choice. – Duck Dodgers Jul 17 '19 at 10:01
  • 6
    Two things unrelated to your problem: First of all ***never ever*** use the `gets` function, it's [dangerous](https://stackoverflow.com/questions/1694036/why-is-the-gets-function-so-dangerous-that-it-should-not-be-used) and have been removed from the C standard. Use e.g. [`fgets`](https://en.cppreference.com/w/c/io/fgets) instead. Second, passing a read-only `FILE` stream to `fflush` (like `stdin`) is explicitly mentioned as *undefined behavior* in the C specification. – Some programmer dude Jul 17 '19 at 10:01

4 Answers4

2

char a[50][50] declares a to be an array of 50 arrays of 50 char.

Then a[0] is an array of 50 char, and so is a[1],a[2]. a[3], and so on up to a[49]. There are 50 separate arrays, and each of them has 50 char.

Since a[0] is an array of 50 char, a[0][0] is a char. In general, a[i][j] is character j of array i.

gets(a[i]) says to read characters from input and put them into a[i]. For this to work, a[i] must be an array of chargets reads multiple characters and puts them in the array. If a[i] were a single character, gets could not work.

Although gets(a[i]) says to put characters into a[i], it works by passing an address instead of passing the array. When an array is used in an expression other than as the operand of sizeof or the address operator &, C automatically converts it to a pointer to its first element. Since a[i] is an array, it is automatically converted to a pointer to its first element (a pointer to a[i][0]). gets receives this pointer and uses it to fill in characters that it reads from the standard input stream.

Eric Postpischil
  • 195,579
  • 13
  • 168
  • 312
1

char a[50][50] declares a as a 50-element array of 50-element arrays of char. That means each a[i] is a 50-element array of char. It will be laid out in memory like:

   +---+
a: |   | a[0][0]
   +---+
   |   | a[0][1]
   +---+
   |   | a[0][2]
   +---+
    ...
   +---+
   |   | a[0][49]
   +---+
   |   | a[1][0]
   +---+
   |   | a[1][1]
   +---+
    ...
   +---+
   |   | a[1][49]
   +---+
   |   | a[2][0]
   +---+ 
    ...

This code is storing up to 50 strings, each up to 49 characters long, in a (IOW, each a[i] can store a 49-character string). In C, a string is a sequence of character values including a 0-valued terminator. For example, the string "hello", is represented as the sequence {'h', 'e', 'l', 'l', 'o', 0}. That trailing 0 marks the end of the string. String handling functions and output functions like puts and printf with the %s specifier need that 0 terminator in order to process the string correctly.

Strings are stored in arrays of character type, either char (for ASCII, UTF-8, or EBCDIC character sets) or wchar_t for "wide" strings (character sets that require more than 8 or so bits to encode). An N-character string requires an array that's at least N+1 elements wide to account for the 0 terminator.

Unless it is the operand of the sizeof or unary & operator, or is a string literal used to initialize an array of character type, an expression of type "N-element array of T" will be converted ("decay") to an expression of type "pointer to T", and the value of the expression will be the address of the first element of the array.

When you call

gets( a[i] );

the expression a[i] is converted from type "50-element array of char" to "pointer to char", and the value of the expression is the address of the first element of the array (&a[i][0])1. gets will read characters from standard input and store them to the array starting at that address. Note that gets is no longer part of the standard C library - it was removed in the 2011 version of the standard because it is unsafe. C does not require any sort of bounds checking on array accesses - if you type in more characters than the target buffer is sized to hold (in this case, 50), those extra characters will be written to memory immediately following the last element of the array, which can cause all sorts of mayhem. Buffer overflows are a popular malware exploit. You should replace the gets call with

fgets( a[i], 50, stdin );

which will read up to 49 characters into a[i] from standard input. Note that any excess characters are left in the input stream.

Also, the behavior of fflush is not defined for input streams2 - there's no good, safe, portable way to clear excess input except to read it using getchar or fgetc.


  1. This is why you got the error message you did when you changed a from char [50][50] to char [50] - in that case, a[i] has type char, not char *, and the value of a[i] is not an address.
  2. Microsoft's Visual Studio C compiler is a notable exception - it will clear excess input from the input stream. However, that's specific to MSVC, and not portable across different compilers. The operation is also a little nonsensical with respect to "flush" semantics.

John Bode
  • 119,563
  • 19
  • 122
  • 198
0

Basically, in C this signifies an array of length 0 to 50 of that contains the character value of 50 in each cell of the array

-2

That program seems to store n names in the array a. It first asks for the number of names, and then the names. The method char *gets(char *str) stores each different line in an entry of a.

n has 2 dimensions. The first refers to the number of names, and the second is for the length of each name. Something like n[number_of_names][lenght_of_name]

However, it will probably crash if the user provides an n > 50, or if a name contains more than 50 chars.

Also, gets() is dangerous. See this other post.

EDIT: Changing a to one dimensions makes the program try to store a whole line inside a char, hence the error

Pablo
  • 377
  • 1
  • 14