Когда я печатаю динамически распределенные массивы, он печатает только последнее значение

#c

#c

Вопрос:

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

Ниже приведен код и выходные данные.

 #include <stdio.h>
#include <stdlib.h>
#include <fcntl.h>
#include <errno.h>
#include <dirent.h>
#include <string.h>
#include <stdbool.h>



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


    char** arrayWithPaths; 

    int counter=0;

    int pathCounter=0;
         
    char *path= (char*) malloc(100*sizeof(char*));

    
    //If the argv is equal with 1 then there is not a path
    //If the argv is equal with 2 then there is a path
    //If the argv is not equal with 1 neither with  2  then there is more than 1 path
    
    if (argc == 1 )
    {
        
    }else if (argc == 2){

        arrayWithPaths = calloc(50,sizeof(char*));
       
       
        DIR *dir = opendir(argv[1]);

        if (dir != NULL){

            struct dirent *dirP;


            while ((dirP = readdir(dir)) != NULL)
            {

                counter  ; 

                if (counter > 2)
                {

                    int len = strlen(argv[1]);
                    char *lastLetter = argv[1] len-1;
                    
                    if (*lastLetter != '/')
                    {
                        sprintf(path,"%s/%s", argv[1], dirP->d_name);
                        arrayWithPaths[pathCounter]=path;
                    }else{
                        sprintf(path,"%s%s", argv[1], dirP->d_name);
                        arrayWithPaths[pathCounter]=path;
                    }
                    
                    pathCounter  ;

                }

               
            }

            
            
        
            
           for (int i = 0; i < pathCounter; i  )
            {
                printf("%d", i);
                printf("%sn",arrayWithPaths[i]);
            }
            
            
            
        free(arrayWithPaths);


        closedir(dir);

        free(path);



        }else if (ENOENT == errno){

            printf("Directory does not existn");

        }

    }else{
        printf("Input only one path!");
        return 1;
    }
    
    
    
    

    return 0;
}
 

Текущий вывод

 /mnt/c/Users/user/Desktop/lslab/text/nameOfSomething.txt
/mnt/c/Users/user/Desktop/lslab/text/nameOfSomething.txt
/mnt/c/Users/user/Desktop/lslab/text/nameOfSomething.txt
/mnt/c/Users/user/Desktop/lslab/text/nameOfSomething.txt
/mnt/c/Users/user/Desktop/lslab/text/nameOfSomething.txt
/mnt/c/Users/user/Desktop/lslab/text/nameOfSomething.txt
 

Вывод, который я хочу

 /mnt/c/Users/user/Desktop/lslab/text/2.txt
/mnt/c/Users/user/Desktop/lslab/text/3.txt
/mnt/c/Users/user/Desktop/lslab/text/4.txt
/mnt/c/Users/user/Desktop/lslab/text/5.txt
/mnt/c/Users/user/Desktop/lslab/text/emptyOne.txt
/mnt/c/Users/user/Desktop/lslab/text/nameOfSomething.txt
 

Ответ №1:

 char path= (char*) malloc(100*sizeof(char*));
 

Хорошо, path это указатель на один выделенный вами блок памяти.

                     arrayWithPaths[pathCounter]=path;
 

Каждый раз в цикле вы добавляете значение path в свой массив. Но значение path никогда не меняется, оно всегда указывает на тот же блок памяти, который вы выделили перед входом в цикл.

Итак, в конце вы проходите цикл и печатаете каждую запись в массиве. Но каждая запись в массиве — это тот же самый указатель на тот же самый блок памяти, который вы выделили в начале, который теперь содержит последнее, что вы в него поместили.

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

Один простой способ сделать это:

                     arrayWithPaths[pathCounter]=strdup(path);
 

strdup Функция каждый раз выделяет новый фрагмент памяти и копирует в него строку, на которую указывает path .

Комментарии:

1. strdup() это POSIX, а не стандартный C, поэтому он может быть недоступен в системах, отличных от POSIX. Однако его почти тривиально реплицировать, что, вероятно, является одной из причин, почему он не является стандартным C.