In this line:

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

You need to make sure word[i] is pointing somewhere, and has enough space to occupy the string entered. Since word[i] is a char * pointer, you need to at some time allocate memory for this. Otherwise, it is just a dangling pointer not pointing anywhere.

If you want to stick with scanf(), then you can allocate some space beforehand with malloc.

malloc() allocates requested memory on the heap, then returns a void* pointer at the end.

You can apply malloc() in your code like this:

size_t malloc_size = 100;

for (i = 0; i < 3; i++) {
    word[i] = malloc(malloc_size * sizeof(char)); /* allocates 100 bytes */
    printf("Enter word: ");
    scanf("%99s", word[i]); /* Use %99s to avoid overflow */
                            /* No need to include & address, since word[i] is already a char* pointer */
} 

Note: Must check return value of malloc(), because it can return NULL when unsuccessful.

Additionally, whenever you allocate memory with the use of malloc(), you must use free to deallocate requested memory at the end:

free(word[i]);
word[i] = NULL; /* safe to make sure pointer is no longer pointing anywhere */

Another approach without scanf

A more proper way to read strings should be with fgets.

char *fgets(char *str, int n, FILE *stream) reads a line from an input stream, and copies the bytes over to char *str, which must be given a size of n bytes as a threshold of space it can occupy.

Things to note about fgets:

  • Appends \n character at the end of buffer. Can be removed easily.
  • On error, returns NULL. If no characters are read, still returns NULL at the end.
  • Buffer must be statically declared with a given size n.
  • Reads specified stream. Either from stdin or FILE *.

Here is an example of how it can be used to read a line of input from stdin:

char buffer[100]; /* statically declared buffer */

printf("Enter a string: ");
fgets(buffer, 100, stdin); /* read line of input into buffer. Needs error checking */

Example code with comments:

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

#define NUMSTR 3
#define BUFFSIZE 100

int main(void) {
    char *words[NUMSTR];
    char buffer[BUFFSIZE];
    size_t i, count = 0, slen; /* can replace size_t with int if you prefer */

    /* loops only for three input strings */
    for (i = 0; i < NUMSTR; i++) {

        /* read input of one string, with error checking */
        printf("Enter a word: ");
        if (fgets(buffer, BUFFSIZE, stdin) == NULL) {
            fprintf(stderr, "Error reading string into buffer.\n");
            exit(EXIT_FAILURE);
        }

        /* removing newline from buffer, along with checking for overflow from buffer */
        slen = strlen(buffer);
        if (slen > 0) {
            if (buffer[slen-1] == '\n') {
                buffer[slen-1] = '\0';
            } else {
                printf("Exceeded buffer length of %d.\n", BUFFSIZE);
                exit(EXIT_FAILURE);
            }
        } 

        /* checking if nothing was entered */
        if (!*buffer) {
            printf("No string entered.\n");
            exit(EXIT_FAILURE);
        }

        /* allocate space for `words[i]` and null terminator */
        words[count] = malloc(strlen(buffer)+1);

        /* checking return of malloc, very good to do this */
        if (!words[count]) {
            printf("Cannot allocate memory for string.\n");
            exit(EXIT_FAILURE);
        }

        /* if everything is fine, copy over into your array of pointers */
        strcpy(words[count], buffer);

        /* increment count, ready for next space in array */
        count++;
    }  

    /* reading input is finished, now time to print and free the strings */
    printf("\nYour strings:\n");
    for (i = 0; i < count; i++) {
        printf("words[%zu] = %s\n", i, words[i]);
        free(words[i]);
        words[i] = NULL;
    }

    return 0;
}

Example input:

Enter a word: Hello
Enter a word: World
Enter a word: Woohoo

Output:

Your strings:
words[0] = Hello
words[1] = World
words[2] = Woohoo
Answer from RoadRunner on Stack Overflow
Top answer
1 of 7
12

In this line:

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

You need to make sure word[i] is pointing somewhere, and has enough space to occupy the string entered. Since word[i] is a char * pointer, you need to at some time allocate memory for this. Otherwise, it is just a dangling pointer not pointing anywhere.

If you want to stick with scanf(), then you can allocate some space beforehand with malloc.

malloc() allocates requested memory on the heap, then returns a void* pointer at the end.

You can apply malloc() in your code like this:

size_t malloc_size = 100;

for (i = 0; i < 3; i++) {
    word[i] = malloc(malloc_size * sizeof(char)); /* allocates 100 bytes */
    printf("Enter word: ");
    scanf("%99s", word[i]); /* Use %99s to avoid overflow */
                            /* No need to include & address, since word[i] is already a char* pointer */
} 

Note: Must check return value of malloc(), because it can return NULL when unsuccessful.

Additionally, whenever you allocate memory with the use of malloc(), you must use free to deallocate requested memory at the end:

free(word[i]);
word[i] = NULL; /* safe to make sure pointer is no longer pointing anywhere */

Another approach without scanf

A more proper way to read strings should be with fgets.

char *fgets(char *str, int n, FILE *stream) reads a line from an input stream, and copies the bytes over to char *str, which must be given a size of n bytes as a threshold of space it can occupy.

Things to note about fgets:

  • Appends \n character at the end of buffer. Can be removed easily.
  • On error, returns NULL. If no characters are read, still returns NULL at the end.
  • Buffer must be statically declared with a given size n.
  • Reads specified stream. Either from stdin or FILE *.

Here is an example of how it can be used to read a line of input from stdin:

char buffer[100]; /* statically declared buffer */

printf("Enter a string: ");
fgets(buffer, 100, stdin); /* read line of input into buffer. Needs error checking */

Example code with comments:

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

#define NUMSTR 3
#define BUFFSIZE 100

int main(void) {
    char *words[NUMSTR];
    char buffer[BUFFSIZE];
    size_t i, count = 0, slen; /* can replace size_t with int if you prefer */

    /* loops only for three input strings */
    for (i = 0; i < NUMSTR; i++) {

        /* read input of one string, with error checking */
        printf("Enter a word: ");
        if (fgets(buffer, BUFFSIZE, stdin) == NULL) {
            fprintf(stderr, "Error reading string into buffer.\n");
            exit(EXIT_FAILURE);
        }

        /* removing newline from buffer, along with checking for overflow from buffer */
        slen = strlen(buffer);
        if (slen > 0) {
            if (buffer[slen-1] == '\n') {
                buffer[slen-1] = '\0';
            } else {
                printf("Exceeded buffer length of %d.\n", BUFFSIZE);
                exit(EXIT_FAILURE);
            }
        } 

        /* checking if nothing was entered */
        if (!*buffer) {
            printf("No string entered.\n");
            exit(EXIT_FAILURE);
        }

        /* allocate space for `words[i]` and null terminator */
        words[count] = malloc(strlen(buffer)+1);

        /* checking return of malloc, very good to do this */
        if (!words[count]) {
            printf("Cannot allocate memory for string.\n");
            exit(EXIT_FAILURE);
        }

        /* if everything is fine, copy over into your array of pointers */
        strcpy(words[count], buffer);

        /* increment count, ready for next space in array */
        count++;
    }  

    /* reading input is finished, now time to print and free the strings */
    printf("\nYour strings:\n");
    for (i = 0; i < count; i++) {
        printf("words[%zu] = %s\n", i, words[i]);
        free(words[i]);
        words[i] = NULL;
    }

    return 0;
}

Example input:

Enter a word: Hello
Enter a word: World
Enter a word: Woohoo

Output:

Your strings:
words[0] = Hello
words[1] = World
words[2] = Woohoo
2 of 7
4

There seems to be a bit of confusion in this area. Your primary problem is you are attempting to write each word to the address of each of pointers you declare with char *word[3];. (not to mention you have no storage allocated at the location pointed to by each pointer -- but you never get there as you attempt to write to the address of each pointer with &word[i] rather than to the pointer itself)

While you can use scanf you will quickly run into one of the many pitfalls with taking user input with scanf that plague all new C programmers (e.g. failing to handle the '\n' left in the input buffer, failing to handle whitespace in strings, failing to limit the number of characters read/written, failing to validate the read or handle EOF, etc...)

A better approach is to simply use fgets and then trim the '\n' that fgets read and includes in the buffer to which it stores the string. A simple example would be:

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

#define NWDS 3    /* declare a constant for the maximum number of words */

int main (void) {

    int i, n = 0;
    char word[NWDS][50] = { "" };       /* provide storage or allocate */

    for (i = 0; i < NWDS; i++) {        /* for a max of NWDS */
        printf ("Enter word : ");       /* prompt */
        if (!fgets (word[i], sizeof word[i], stdin))  /* read/validate */
            break;                      /* protect against EOF */
        size_t len = strlen (word[i]);  /* get length */
        if (word[i][len-1] == '\n')     /* check for trailing '\n' */
            word[i][--len] = 0;         /* overwrite with nulbyte  */
    }
    n = i;                              /* store number of words read */
    putchar ('\n');                     /* make it pretty */

    for (i = 0; i < n; i++)             /* output each word read */
        printf (" word[%d] : %s\n", i, word[i]);

#if (defined _WIN32 || defined _WIN64)
    getchar();  /* keep terminal open until keypress if on windows */
#endif

    return 0;
}

Go ahead and cancel input at any time by generating an EOF during input (ctrl + d on Linux or ctrl + z on windoze), you are covered.

Example Use/Output

$ ./bin/wordsread
Enter word : first word
Enter word : next word
Enter word : last word

 word[0] : first word
 word[1] : next word
 word[2] : last word

Looks things over, consider the other answers, and let me know if you have further questions.

๐ŸŒ
GeeksforGeeks
geeksforgeeks.org โ€บ c language โ€บ array-of-strings-in-c
Array of Strings in C - GeeksforGeeks
July 23, 2025 - In C, an array of strings is a 2D array where each row contains a sequence of characters terminated by a '\0' NULL character (strings).
๐ŸŒ
Quora
quora.com โ€บ How-do-I-declare-an-array-of-strings-that-are-inputted-by-the-user-in-C
How to declare an array of strings that are inputted by the user in C - Quora
Answer (1 of 2): There are two ways, 1. Using structure for eg, struct string{ char str[100]; }STRING[100]; 2. Or by using char string[100][100]; I generally prefer using structure as it results in more cleaner code.
๐ŸŒ
Medium
medium.com โ€บ @divyasrdj โ€บ programming-in-c-arrays-strings-1695160875a3
Programming in C โ€” Arrays & Strings | by Divya Stephen | Medium
June 16, 2025 - Here, we have used a for loop to take five inputs and store them in an array. Then, these elements are printed using another for loop. In C, an enumerated type (enum) is a user-defined data type that assigns names to integral constants. It enhances code readability and maintainability by using meaningful names instead of raw numbers.
๐ŸŒ
OverIQ
overiq.com โ€บ c-programming-101 โ€บ array-of-strings-in-c
Array of Strings in C - C Programming Tutorial - OverIQ.com
The ch_arr is a pointer to an array of 10 characters or int(*)[10]. Therefore, if ch_arr points to address 1000 then ch_arr + 1 will point to address 1010. ... ch_arr + 0 points to the 0th string or 0th 1-D array. ch_arr + 1 points to the 1st string or 1st 1-D array.
๐ŸŒ
W3Schools Blog
w3schools.blog โ€บ home โ€บ create array of strings in c from user input
create array of strings in c from user input - W3schools
June 27, 2022 - [ad_1] create array of strings in c from user input #include int main() { char str[5][10]; printf("enter the strings...n"); for(int i =0; i
๐ŸŒ
HackerEarth
hackerearth.com โ€บ practice โ€บ notes โ€บ array-and-strings-code-monk
Arrays and Strings - Code Monk - Prateek Garg
str is a string which has an instance (string literal) โ€œHELLOโ€. In spite of only 5 characters, the size of the string is 6, because the null character represents the end of the string. The null character is automatically added by the compiler as long as the size of the array is at least one larger than the size of the string. It is not mandatory that the array size (N) be exactly greater than the size of the string (n) by 1 i.e. N >= n + 1 ยท To take C-style string as an input you can simple use scanf() with โ€˜%sโ€™ format specifier or we can also use cin.
Find elsewhere
๐ŸŒ
TutorialsPoint
tutorialspoint.com โ€บ home โ€บ cprogramming โ€บ c array of strings
C Array of Strings
June 10, 2012 - To declare an array of strings, ... string. To initialize an array of strings, you need to provide the multiple strings inside the double quotes separated by the commas....
๐ŸŒ
WsCube Tech
wscubetech.com โ€บ resources โ€บ c-programming โ€บ array-of-strings
Array of Strings in C Language (With Examples)
November 10, 2025 - Learn how to create and use an array of strings in C programming. Explore different methods and operations with examples, output, and explanations. Read now!
๐ŸŒ
Programiz
programiz.com โ€บ c-programming โ€บ c-strings
Strings in C (With Examples)
Here, we have used fgets() function to read a string from the user. ... The sizeof(name) results to 30. Hence, we can take a maximum of 30 characters as input which is the size of the name string.
๐ŸŒ
GeeksforGeeks
geeksforgeeks.org โ€บ c language โ€บ strings-in-c
Strings in C - GeeksforGeeks
November 14, 2025 - This null character marks the end of the string and is essential for proper string manipulation. Unlike many modern languages, C does not have a built-in string data type. Instead, strings are implemented as arrays of char.
Top answer
1 of 2
3

Yes, but you need to make sure you have enough space to do so:

char input[3][50]; // enough space for 3 strings with
                   // a length of 50 (including \0)

fgets(&input[0], 50, stdin);
printf("Inputted string: %s\n", input[0]);

Using char **input does not have any space allocated for the input, therefore you cannot do it.

2 of 2
3

It's possible, but somewhat tedious, especially if you don't know the number of strings at the beginning.

char **input;

That much is fine. From there, you need allocate an array of (the right number of) pointers:

input = malloc(sizeof(char *) * MAX_LINES);

Then you need to allocate space for each line. Since you typically only want enough space for each string, you typically do something like this:

#define MAX_LINE_LEN 8192

static char buffer[MAX_LINE_LEN];
long current_line = 0;

while (fgets(buffer, sizeof(buffer), infile) && current_line < MAX_LINES)  {
    input[current_line] = malloc(strlen(buffer)+1);
    strcpy(buffer[current_line++], buffer);
}

If you don't know the number of lines up-front, you typically allocate a number of pointers to start with (about as above), but as you read each line, check whether you've exceeded the current allocation, and if you have realloc the array of pointers to get more space.

If you want to badly enough, you can do the same with each individual line. Above, I've simply set a maximum that's large enough you probably won't exceed it very often with most typical text files. If you need it larger, it's pretty easy to expand that. At the same time, any number you pick will be an arbitrary limit. If you want to, you can read a chunk into your buffer, and if the last character in the string is not a new-line, keep reading more into the same string (and, again, use realloc to expand the allocation as needed). This isn't terribly difficult to do, but covering all the corner cases correctly can/does get tedious.

Edit: I should add that there's a rather different way to get the same basic effect. Read the entire content of the file into a single big buffer, then (typically) use strtok to break the buffer into lines (replacing "\n" with "\0") to build an array of pointers into the buffer. This typically improves speed somewhat (one big read instead of many one-line reads) as well as allocation overhead because you use one big allocation instead of many small ones. Each allocation will typically have a header, and get rounded to something like a (multiple of some) power of two. The effect of this varies with the line length involved. If you have a few long lines, it probably won't matter much. If you have a lot of short lines, it can save a lot.

Top answer
1 of 2
3

The process is basically the same regardless of whether you read from stdin or read from a file. You either read each line with line-oriented input (fgets or getline) or you use character-oriented input (getchar, fgetc, etc). (the scanf family falls in the middle). When reading lines, generally the best choice is line-oriented input.

When reading user input into an array, you have two choices, either declare a static array of pointers and hope you allocated enough pointers to begin with, or you dynamically allocate the array of pointers and realloc as needed to hold all input. (who knows, the user might redirect a file for reading). When you allocate anything dynamically you are responsible to track its use, preserve a pointer to the original starting address for the block of memory, and freeing the memory when it is no longer needed.

The following is a standard example of taking input from stdin and storing it in a dynamically allocated array. There is a twist. The code can handle input from a file or stdin. If a filename is given as the first argument, then it will read the file, otherwise it reads from stdin. It expects the user to provide as much input as required, and then press [ctrl+d] when done. (manually generating EOF).

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

#define NMAX 128

int main (int argc, char **argv) {

    char *ln = NULL;                /* NULL forces getline to allocate  */
    size_t n = 0;                   /* initial ln size, getline decides */
    ssize_t nchr = 0;               /* number of chars actually read    */
    size_t idx = 0;                 /* array index counter              */
    size_t nmax = NMAX;             /* check for reallocation           */
    char **array = NULL;            /* array to hold lines read         */
    FILE *fp = NULL;                /* file pointer to open file fn     */

    if (argc > 1) {
        if (!(fp = fopen (argv[1], "r"))) {
            fprintf (stderr, "error: file open failed for '%s'\n", argv[1]);
            return 1;
        }
    }
    else
        fp = stdin;

    /* allocate NMAX pointers to char* */
    if (!(array = calloc (NMAX, sizeof *array))) {
        fprintf (stderr, "error: memory allocation failed.");
        return 1;
    }

    if (fp == stdin)
        printf ("\nEnter information to store in array on each line, [ctrl+d] when done:\n\n");

    /* read each line from file or stdin - dynamicallly allocated   */
    while ((nchr = getline (&ln, &n, fp)) != -1)
    {
        /* strip newline or carriage rtn    */
        while (nchr > 0 && (ln[nchr-1] == '\n' || ln[nchr-1] == '\r'))
            ln[--nchr] = 0;

        array[idx] = strdup (ln);   /* allocate/copy ln to array        */

        idx++;                      /* increment value at index         */

        if (idx == nmax) {          /* if lines exceed nmax, reallocate */
            char **tmp = realloc (array, nmax * 2 * sizeof *tmp);
            if (!tmp) {
                fprintf (stderr, "error: memory exhausted.\n");
                break;
            }
            array = tmp;
            nmax *= 2;
        }
    }

    if (ln) free (ln);              /* free memory allocated by getline */
    if (fp != stdin) fclose (fp);   /* close open file descriptor       */

    size_t i = 0;

    /* print array */
    printf ("\nThe lines in the file are:\n\n");
    for (i = 0; i < idx; i++)
        printf (" line[%3zu] : %s\n", i, array[i]);

    /* free array */
    for (i = 0; i < idx; i++)
        free (array[i]);
    free (array);

    return 0;
}

Example/Output

$ ./bin/getline_readstdin_dyn

Enter information to store in array on each line, [ctrl+d] when done:

This is a line of input
This is another
and another
etc..

The lines in the file are:

 line[  0] : This is a line of input
 line[  1] : This is another
 line[  2] : and another
 line[  3] : etc..

Or reading from a file:

$ ./bin/getline_readstdin_dyn dat/ll_replace_poem.txt

The lines in the file are:

 line[  0] : Eye have a spelling chequer,
 line[  1] : It came with my Pea Sea.
 line[  2] : It plane lee marks four my revue,
 line[  3] : Miss Steaks I can knot sea.
 line[  4] : Eye strike the quays and type a whirred,
 line[  5] : And weight four it two say,
 line[  6] : Weather eye am write oar wrong,
 line[  7] : It tells me straight aweigh.
 line[  8] : Eye ran this poem threw it,
 line[  9] : Your shore real glad two no.
 line[ 10] : Its vary polished in its weigh.
 line[ 11] : My chequer tolled me sew.
 line[ 12] : A chequer is a bless thing,
 line[ 13] : It freeze yew lodes of thyme.
 line[ 14] : It helps me right all stiles of righting,
 line[ 15] : And aides me when eye rime.
 line[ 16] : Each frays come posed up on my screen,
 line[ 17] : Eye trussed too bee a joule.
 line[ 18] : The chequer pours over every word,
 line[ 19] : Two cheque sum spelling rule.

Redirecting input is fine as well. E.g.:

$ ./bin/getline_readstdin_dyn < dat/ll_replace_poem.txt
2 of 2
0

At the risk of advising parse kludge, you have your read loop. Now use strtok or sscanf to parse string by tokens into storage variables. In this setup I suspect strdup is the better choice.

๐ŸŒ
YouTube
youtube.com โ€บ watch
Initialize An Array Of Strings With User Input | C Programming ...
Enjoy the videos and music you love, upload original content, and share it all with friends, family, and the world on YouTube.
๐ŸŒ
GeeksforGeeks
geeksforgeeks.org โ€บ c language โ€บ how-to-store-words-in-an-array-in-c
How to store words in an array in C? - GeeksforGeeks
October 18, 2019 - // C program to store words in an array #include <stdio.h> int main() { int i; // Direct initialization of 2-D char array char array[][20] = { "Geek1", "Geek2", "Geek3" }; // print the words for (i = 0; i < 3; i++) printf("%s\n", array[i]); return 0; } ... By taking input from user: In this method, the number of words and words are given by the user and we have to create and map the 2-D char array for each word.
Top answer
1 of 15
305

If you don't want to change the strings, then you could simply do

const char *a[2];
a[0] = "blah";
a[1] = "hmm";

When you do it like this you will allocate an array of two pointers to const char. These pointers will then be set to the addresses of the static strings "blah" and "hmm".

If you do want to be able to change the actual string content, the you have to do something like

char a[2][14];
strcpy(a[0], "blah");
strcpy(a[1], "hmm");

This will allocate two consecutive arrays of 14 chars each, after which the content of the static strings will be copied into them.

2 of 15
251

There are several ways to create an array of strings in C. If all the strings are going to be the same length (or at least have the same maximum length), you simply declare a 2-d array of char and assign as necessary:

char strs[NUMBER_OF_STRINGS][STRING_LENGTH+1];
...
strcpy(strs[0], aString); // where aString is either an array or pointer to char
strcpy(strs[1], "foo");

You can add a list of initializers as well:

char strs[NUMBER_OF_STRINGS][STRING_LENGTH+1] = {"foo", "bar", "bletch", ...};

This assumes the size and number of strings in the initializer match up with your array dimensions. In this case, the contents of each string literal (which is itself a zero-terminated array of char) are copied to the memory allocated to strs. The problem with this approach is the possibility of internal fragmentation; if you have 99 strings that are 5 characters or less, but 1 string that's 20 characters long, 99 strings are going to have at least 15 unused characters; that's a waste of space.

Instead of using a 2-d array of char, you can store a 1-d array of pointers to char:

char *strs[NUMBER_OF_STRINGS];

Note that in this case, you've only allocated memory to hold the pointers to the strings; the memory for the strings themselves must be allocated elsewhere (either as static arrays or by using malloc() or calloc()). You can use the initializer list like the earlier example:

char *strs[NUMBER_OF_STRINGS] = {"foo", "bar", "bletch", ...};

Instead of copying the contents of the string constants, you're simply storing the pointers to them. Note that string constants may not be writable; you can reassign the pointer, like so:

strs[i] = "bar";
strs[i] = "foo"; 

But you may not be able to change the string's contents; i.e.,

strs[i] = "bar";
strcpy(strs[i], "foo");

may not be allowed.

You can use malloc() to dynamically allocate the buffer for each string and copy to that buffer:

strs[i] = malloc(strlen("foo") + 1);
strcpy(strs[i], "foo");

BTW,

char (*a[2])[14];

Declares a as a 2-element array of pointers to 14-element arrays of char.

๐ŸŒ
Studytonight
studytonight.com โ€บ c โ€บ string-and-character-array.php
String and Character Arrays in C Language | Studytonight
Learn how to create a string, character arrays in C, string input and output and string functions in C.