Rather than statically specifying a 2D array, you are better served by specifying an array of pointers and then allocating memory for each string added to the array. While fgets
or getline
is preferred, there is nothing wrong with allocating memory with scanf
. (Note: the current version of scanf
uses m
prior to the conversion specifier for allocation, windows and earlier version used a
for this purpose). When using scanf
to allocate, scanf
expects a pointer argument of type char **
to hold the allocated string. When you allocate memory, regardless of how, you are responsible for freeing the memory when it is no longer required. Taking that into consideration, your code could be written as follows:
#include <stdio.h>
#include <stdlib.h>
#define MAXD 64
int main() {
char *string[MAXD];
int line = 0;
int i = 0;
printf ("\nHome many lines: ");
scanf ("%d%*c", &line);
if (line > MAXD) { /* validate line <= MAXD pointers */
fprintf (stderr, "warning: request exceeds %d limit.\n", MAXD);
line = MAXD;
}
/* scanf will allocate if given 'm' ('a' on Win & earlier versions)
as part of the specification before the conversion specifier */
for (i = 0; i < line; i++) {
printf ("\n input: ");
scanf ("%m[^\n]%*c", &string[i]);
}
printf ("\nYou entered:\n\n");
for (i = 0; i < line; i++)
printf (" string[%d] : %s\n", i, string[i]);
printf ("\n");
/* free the memory allocated by scanf */
for (i = 0; i < line; i++)
free (string[i]);
return 0;
}
Use/Output
$ ./bin/scanf_string_dyn
Home many lines: 4
input: this is line 1
input: this is line 2
input: this is line 3
input: this is line 4
You entered:
string[0] : this is line 1
string[1] : this is line 2
string[2] : this is line 3
string[3] : this is line 4
You can adjust the number of pointers by adjusting the MAXD
define. (you can also dynamically allocate and reallocate them as necessary, but that is beyond the scope of your question)