Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Welcome To Ask or Share your Answers For Others

Categories

0 votes
86 views
in Technique[技术] by (71.8m points)

How to input strings into an array in C?

I tried to get the inputs(strings) from user and store them in an array.But after I ran this code, the program instantly crashed.

#include <stdio.h>
int main() {
    int i;
    char *word[3];
    for(i=0;i<3;i++)
    {
        printf(" Enter a word: ");
        scanf("%s", &word[i]);
    }
    printf("%s ", word[0]);
    return 0;
}
question from:https://stackoverflow.com/questions/65914298/read-from-standard-input-and-store-in-an-array-on-c

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
Welcome To Ask or Share your Answers For Others

1 Reply

0 votes
by (71.8m points)

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 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.
");
            exit(EXIT_FAILURE);
        }

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

        /* checking if nothing was entered */
        if (!*buffer) {
            printf("No string entered.
");
            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.
");
            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("
Your strings:
");
    for (i = 0; i < count; i++) {
        printf("words[%zu] = %s
", 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

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
OGeek|极客中国-欢迎来到极客的世界,一个免费开放的程序员编程交流平台!开放,进步,分享!让技术改变生活,让极客改变未来! Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Click Here to Ask a Question

...