Массив строки в C: ОК внутри функции, полный мусор в main () - PullRequest
0 голосов
/ 22 апреля 2020

Массив строк создается в main и передается функции. Эта функция читает строки из файла и сохраняет каждую строку файла в другой строке массива. Затем заканчивается и возвращается к основному. Если я распечатаю содержимое массива [i] внутри функции, текст, отображаемый на экране, в порядке. Если я сделаю то же самое после возврата к main (), printf пишет только мусор. Почему main () не обращается к содержимому позиций памяти массива?

void createlist(char* file, char **mylist) {

    FILE* stream;
    char name[40];
    int i = 0;

    stream = fopen(file, "r");      

    while (fgets(name, sizeof(name), stream) != NULL) { 

        mylist[i] = name;
        printf(mylist[i]);   // <------------------------This works OK! 
        i++;
    }
    fclose(stream);
}

void main(int argc, char* argv[]) {

    char list[3000][40]; 
    int i = 0;
    resetchararray(list, 3000);

    createlist("file", list);   

    for (i = 0; i < 3000; i++) {
        printf(list[i]);    // <---------------------This writes garbage
    }
}

Ответы [ 2 ]

0 голосов
/ 23 апреля 2020

Компиляция вашего кода выдает предупреждение:

program.c:26:24: warning: passing argument 2 of ‘createlist’ from incompatible pointer type [-Wincompatible-pointer-types]
     createlist("file", list);   
                    ^
program.c:3:6: note: expected ‘char **’ but argument is of type ‘char (*)[40]’
 void createlist(char* file, char **mylist) {

, которое говорит вам о том, что является одной из ваших проблем - указатель, который вы передаете на createlist, является неправильным типом. Как объявлено, createlist ожидает массив указателей, но вы пытаетесь передать массив массивов. Существуют и другие проблемы, такие как сохранение адреса локальной переменной в массиве указателей, которая будет недействительной после возврата из функции.

0 голосов
/ 22 апреля 2020

name - это локальная переменная в вашей функции. Он исчезает после завершения функции и оставляет только мусор. Чтобы добиться того, что вы пытаетесь, используйте strcpy() вместо mylist[i] = name;.

Что происходит в данный момент:

  1. createlist("file", list); pass list по значению @ Shark предупреждает!
  2. mylist[i] = name; заставляет mylist[i] содержать адрес локальной переменной!
  3. createlist() завершается, изменив только локальную копию list ( см. пункт 1)
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...