C将字符串存储到数组中

时间:2016-12-04 04:36:44

标签: c arrays string

我正在解决一个问题来自" C编程现代方法第2版"文本。我想编写一个编写最小和最大单词的程序。当用户输入一个4个字母的单词时,程序停止接受输入。

我使用一系列字符串来解决这个问题,但我甚至无法让我的程序在其中存储文字。

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

#define WORD_LEN 20

int main()
{
    char word[WORD_LEN]={0},ch;
    char *a[10]={};            //Max 10 words in the array
    int i=0,j;

    for(;;)
    {
        printf("Enter a word: ");
        fgets(word,WORD_LEN,stdin);
        strtok(word, "\n");             //removes newline

        a[i] = word;
        if(strlen(word) == 4)          //if word is 4 characters
            break;                     //break out of loop

        i++;
    }

    for(j=0;j<i;j++)                      //displaying array
        printf("%s\n",a[j]);

    return 0;
}

输出:

Enter a word: Analysis
Enter a word: Martin
Enter a word: Jonathan
Enter a word: Dana
Dana
Dana
Dana

对我做错了什么的想法?感谢。

2 个答案:

答案 0 :(得分:2)

正如BLUEPIXY所提到的,你在所有[i]中存储了相同的地址。所以在循环结束时,它会打印最后一次输出。

解决方案: 您需要为[i]分配内存并复制字符串。

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

#define WORD_LEN 20
#define MAX_NUM_WORD 10 //Max 10 words in the array

int main()
{
    char word[WORD_LEN]={0},ch;
    char *a[MAX_NUM_WORD]={0};            
    int i=0,j;

    for(;;)
    {
        printf("Enter a word: ");
        fgets(word,WORD_LEN,stdin);
        strtok(word, "\n");             //removes newline

        a[i] = malloc(sizeof(char)* (strlen(word)+1)); //1 for '\0'

        strcpy(a[i], word);

        i++;
        if(strlen(word) == 4)          //if word is 4 characters
            break;                     //break out of loop

        //i++; //You will be missing last 4 letter word if i++ is here.
        if(MAX_NUM_WORD <= i) //You can store only MAX_NUM_WORD strings
            break;
    }

    for(j=0;j<i;j++)                      //displaying array
        printf("%s\n",a[j]);

   //Your other code.

    for(i=0; i<MAX_NUM_WORD && NULL != a[i]; i++)
        free(a[i]); //Free the allocated memory.

    return 0;
}

答案 1 :(得分:1)

添加其他答案,当使用malloc为字符串分配内存时,最好还检查从其返回的void*指针的返回值。

此外,检查fgets的返回值也是安全的,只是为了超级安全。

此解决方案证明了这些要点:

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

#define WORD_LEN 20
#define MAX_NUM_WORD 10
#define EXIT_LEN 4

int 
main(void) {
    char word[WORD_LEN];
    char *a[MAX_NUM_WORD];
    int i = 0, wrd;

    while (i < MAX_NUM_WORD) {
        printf("Enter a word: ");
        if (fgets(word, WORD_LEN, stdin) != NULL) {
            word[strlen(word)-1] = '\0';
        }

        a[i] = malloc(strlen(word)+1);
        if (a[i] == NULL) {
            fprintf(stderr, "%s\n", "Malloc Problem");
            exit(EXIT_FAILURE);
        }

        strcpy(a[i], word);

        i++;

        if (strlen(word) == EXIT_LEN) {
            break;
        }

    }

    // Print and free, all at once. 
    for (wrd = 0; wrd < i; wrd++) {
        printf("%s\n", a[wrd]);
        free(a[wrd]);
        a[wrd] = NULL;
    }

    return 0;
}