Search code examples
cstringdir

Adding to strings in C while listing Directories


I am trying to list a directories in a specific Dir in C. But the problem is when I want to add the path and the dir name. I wrote a function to add the path and dir name.

void setNewString(char* str1,char* str2)
{
    // Declare new buffer
    char* buffer = malloc(strlen(str1) + 1);

    // Set the buffer to be str1
    int m = 0,n = 0, o = 0;
    for (int p = strlen(str1); m < p; m++)
    {
        buffer[m] = str1[m];
    }
    buffer[m] = '\0';

    // Set str1 to be str2
    for(int q = strlen(str2);n < q; n++)
    {
        str1[n] = str2[n];   
    }

    // Continue the str1 and buffer to end.
    while(buffer[o] != '\0')
    {
        str1[n] = buffer[o];
        n++;
        o++;
    }
    str1[n] = '\0';

    // Free Buffer
    free(buffer);   
}

And there is while loop to add the dir name together

while ((awesome_controller = readdir(awesome_dir)) != NULL)
{
    if ((awesome_controller->d_type) == 4 && strcmp(awesome_controller->d_name,"..") != 0 && strcmp(awesome_controller->d_name,".") != 0)
    {
      // List All the folders.
      size = ((strlen(temp_awesome)) + (strlen(awesome_controller->d_name)) + 2);
      baby_dir[i] = malloc(size);
      printf("Size:%i\n",size);
      baby_dir[i] = awesome_controller->d_name;
      setNewString(baby_dir[i],temp_awesome);
      i++;  
    }
}

for example if I type in the dir: home/khaledmohammad/vhosts/

I get only 1 dir path: Output:

Size:30
Dir 0: /home/khaledmohammad/vhosts/vcipher

But I know there are 3 dirs.

But when I change the setNewString() function's 15th number line

To

for(int q = strlen(str1);n < q; n++)

From

for(int q = strlen(str2);n < q; n++)

it seems to give me 3 dirs output but not complete.

Output:

Size:30
Size:28
Size:32
Dir 0: /home/kvcipher
Dir 1: /homepset7
Dir 2: /home/khalocalhost

This happens because obviously when is set it to strlen of str2 the loop exits mysteriously.And I don't know why.

So my questions are:

1) Why this happens?

2) How to fix it?

3) And was my setNewString() function good enough or I have mistakes or there is a better way of doing it?


Solution

  • Here is setNewString() implemented via the standard string manipulation functions:

    void setNewString(char* str1,char* str2)
    {
        // Create a copy of str1 in newly-allocated memory
        char* buffer = strdup(str1);
    
        // make the existing str1 a copy of str2
        strcpy(str1, str2);    
    
        // append buffer to str1
        strcat(str1, buffer);
    
        // free the buffer
        free(buffer);   
    }
    

    Note also that whereas this...

    baby_dir[i] = malloc(size);
    

    ... is basically ok, when you combine it with this ...

    baby_dir[i] = awesome_controller->d_name;
    

    ... you have a memory leak. It looks like you probably want the second line to be a strcpy() instead, as @BLUEPIXY suggested.

    But then you're seriously overlapping the actual behavior of setNewString(). Personally, I'd drop setnewString() altogether, and just write the main loop like this:

    while ((awesome_controller = readdir(awesome_dir)) != NULL)
    {
        if ((awesome_controller->d_type) == 4 && strcmp(awesome_controller->d_name,"..") != 0 && strcmp(awesome_controller->d_name,".") != 0)
        {
          // List All the folders.
          size = ((strlen(temp_awesome)) + (strlen(awesome_controller->d_name)) + 2);
          baby_dir[i] = malloc(size);
          printf("Size:%i\n",size);
          strcpy(baby_dir[i], temp_awesome);
          strcat(baby_dir[i], awesome_controller->d_name);
          i++;  
        }
    }