Trial and error is nice to learn. But at a moment, things are to be cleaned up.
First do not cast malloc in C: it is useless and can only let nasty bugs be silent.
Then you are using 2 dynamically allocated arrays of strings phrases
and aux
and at a moment just use:
phrases=aux;
This is bad, because it will leak the memory previously pointed to by phrases: it is still allocated, but you can neither access to it nor even free it until the end of the program.
Keep It Stupid Simple is a good rule. Here you could forget aux
and only use phrases
.
Anyway your real question is about how to know that a Ctrl Z was typed? Well a Ctrl-Z on Windows or Ctrl-D on Unix-like generate and end of file condition when typed on a terminal - they have no effect when read from a file or pipe...
fgets
return NULL on end of file (or error) so you should test that in your loop. And do not try to find a clever while
here because the read has to come after a prompt and the test has to come immediately after the read. So stick to a good old for (;;) { ... break; ...}
And last, fgets
reads up to an end of line and keep it into the buffer. So there is no need to display an additional one after printing your phrases unless you want to make clear what happens with lines longer than 99 characters
After all that, you code could become:
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
int main()
{
char words[100], **phrases /*, **aux */;
int c=0;
phrases=(char **)malloc(1*sizeof(char *));
if (phrases==NULL) exit(1);
/* aux=(char **)malloc(1*sizeof(char *));
if (aux==NULL) exit(1); */
for(;;) {
printf("Enter phrase: ");
if (NULL == fgets(words, 100, stdin)) break; // exit loop on end of file
phrases[c]=(char *)malloc(strlen(words)*sizeof(char)); // note sizeof(char) is 1 by definition
if (phrases[c]==NULL) exit(1);
strcpy(phrases[c], words);
c++;
phrases=(char **)realloc(phrases, (c+1)*sizeof(char *));
if (phrases==NULL) exit(1);
}
printf("\n"); // skip a line here to go pass the prompt
for (int i=0; i<c; i++) {
fputs(phrases[i], stdout);
//printf("\n"); // you can keep it to make long lines splitted
}
for (int i=0; i<c; i++) free (phrases[i]); // ok free the strings
free (phrases); // then the array
return 0;
}
Minor improvements: sizeof(char)
can be omitted because it is 1 by definition. But you can leave it if you find it more clear or simply more consistent.