Сохранять строки из файла в динамически распределенный массив - PullRequest
0 голосов
/ 31 декабря 2018

Я читаю слова из файла, точное число 2243. И я пытаюсь сохранить их внутри массива, чтобы потом прочитать их в программе.Код внутри функции.В файле нет предложений, только слова одно под другим.

char** fill_word_array(char* filename){
    int i = 0, j = 0;
    int lines = 0;

    char str[20];
    char *array[i][j];

    array[i][j] = malloc(lines * sizeof(char*));


    FILE * fp = fopen("words.txt", "r");
    if (fp == NULL)
    {
        printf("Cannot open file");
        return 0;
    }

    while (fscanf(fp, "%s", str) != EOF)
    {
        lines++;
    }
    printf("%d\n", lines);

    fseek(fp, 0, SEEK_SET);

    array[i][j] = malloc(sizeof(char*) * lines);
    for(i = 0; i <= lines; i++)
    {
        strcpy(array[lines][j], str);
        printf("%s", array[i][j]);
    }

    return 0;
}

Этот код печатает только последнее слово файла, как показано здесь http://tinypic.com/r/2zhjmgx/9.

1 Ответ

0 голосов
/ 31 декабря 2018

Объявление типа char *array[i][j] с i==0 и j==0 зарезервирует массив размера 0, так что четная позиция array[0][0] юридически недоступна (неопределенное поведение).Поэтому, когда вы пишете array[i][j] = malloc(lines * sizeof(char*)), вы уже пишете array[0][0], что приводит к UB.

Обычно сообщество наказывает человека за то, что он предоставил решение кому-то, обращающемуся за помощью, и тем самым предоставил ему возможность самостоятельно получить опыт.Для вашего уровня зрелости, однако, мне кажется, что это тяжелое упражнение, и поэтому я предоставлю решение, следуя вашему подходу, и опишу то, что следует учитывать.

Надеюсь, это поможет.

При вашем подходе вам нужно ...

  1. считать слова
  2. выделять место для "слов * sizeof (char *)" + одно слово для хранения NULL - указатель в конце (иначе пользователи вашего результата не будут знать, где остановиться).
  3. перематывать и читать каждое слово в цикле;
  4. в цикле, сделатьскопируйте содержимое временного слова и сохраните его в массиве
  5. после цикла, запишите окончательный NULL-указатель.
  6. верните массив (и сообщите пользователю, что ему придется освободить памятьпозже)

Вот код:

char** fill_word_array(char* filename){

    int words = 0;
    char str[100];
    char **array;

    FILE * fp = fopen("words.txt", "r");
    if (fp == NULL)
    {
        printf("Cannot open file");
        return 0;
    }

    while (fscanf(fp, "%s", str) != EOF)
    {
        words++;
    }
    printf("%d\n", words);

    fseek(fp, 0, SEEK_SET);

    array = malloc(sizeof(char*) * (words+1));
    for(int i = 0; i < words && fscanf(fp, "%s", str) != EOF; i++)
    {
        array[i] = strdup(str);
    }
    array[words] = NULL;

    return array;
}

int main() {

    char **array = fill_word_array("someFile.txt");
    for (int i=0; array[i] != NULL; i++) {
        printf("%s\n", array[i]);
        free(array[i]);
    }
    free(array);
}
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...