Local variables defined inside functions will, unless explicitly initialized, have an indeterminate value. For pointers that means they are pointing at a seemingly random location. Using any uninitialized variable, except to initialize it, leads to undefined behavior.
What happens here is that fgets
will use the (uninitialized and seemingly random) pointer and use it to write into the memory it points to. This memory is in most cases not belonging to you or your program, and might even overwrite some other important data. This can lead to crashes, or other weird behavior or results.
The simplest solution is to make str
an array of arrays of characters, like
#define NUM_OF_STRINGS 2
#define STRING_LENGTH 64
...
char str[NUM_OF_STRINGS][STRING_LENGTH];
...
fgets(str[i], sizeof str[i], stdin);
You need to make sure that STRING_LENGTH
above is enough to fit every string including the newline and the string terminator. In the case of what I show above with it being 64
that means you can have lines of at most 62 characters.
Now as for the other problem I pointed out, with the first call to fgets
reading an empty line.
If you have the input
2 2
hello
The input is stored in a buffer in memory, and then scanf
and fgets
reads from this buffer. The buffer will, with the above input, look something like this
+----+----+----+----+----+----+----+----+----+
| 2 | 2 | \n | h | e | l | l | o | \n |
+----+----+----+----+----+----+----+----+----+
After the scanf
call read the two numbers the input buffer looks like
+----+----+----+----+----+----+----+
| \n | h | e | l | l | o | \n |
+----+----+----+----+----+----+----+
So what the very first call to fgets
in the loop will see is the newline. So it reads that newline and then it's done, leaving the string "hello\n"
in the buffer for the second call to fgets
.
There are a few ways to solve this problem. The one I personally prefer is to use fgets
universally to read lines, and if you need a simple parsing of the line, then use sscanf
(note the leading s
, also please see here for a good reference of all scanf
variants) to do so.
Another way is to simply read characters from the input, one character at a time, and discarding them. When you read a newline, stop the loop and continue with the rest of the program.