0

I'm trying to travel a char array char by char and copy it into another char array until the read character is \ because I want to create the directories of the adress if not created or access if they are created.

For example:

Adress: dir2/dir3/a

My algorithm:

path = dir2
//if dir2 not created make dir2 and change actual directory to dir2
//if created then access dir2 changing the actual directory to dir2
//empty path with memset and keep storing the adress
path = dir3
//repeat...

But when I try to access path I get the last character and not all the path string

Output:

path0: d
path1: i //Should be di
path2: r //Should be dir
path3: 2 //Should be dir2
path: 2 //Should be dir2

I don't know if there is a more efficient way to do this and I don't know how to get the complete path string and not the last character, I was inserting '\0' at the end just in case it was some problem with the string end character

name and path are a char[256] variable
Code:

for (i = 0; i < strlen(name); i++) 
        {
            if(name[i] != '/')
            {
                path[j] = name[i];
                path[i+1] = '\0';
                printf("path%d: %s\n", i,path);
            }
            else
            {
                path[i] = '\0';
                printf("path: %s\n", path);
                n = chdir(path);
                if(n == ENOENT)
                {
                    n = mkdir(path, 0777);
                    if (n != 0) 
                    {
                        fprintf(stderr, "Failed to make the directory to extract: %s\n", strerror(errno));
                        close(fmypack);
                        return E_DIR1;
                    }
                    chdir(path);
                }
                else if(n == EACCES)
                {
                        fprintf(stderr, "Failed to access the directory: %s, %s\n", path, strerror(errno));
                        close(fmypack);
                        return E_DIR2;
                }
                else if(n != 0)
                {
                        fprintf(stderr, "Unknow error when try to access the directory: %s, %s\n", path, strerror(errno));
                        close(fmypack);
                        return E_DESCO;
                }
                memset(path, 0, sizeof path);
                j=0;
            }
JamesR
  • 105
  • 7
  • Don't do `chdir()` — `mkdir()` will take a path quite happily referring to a subdirectory. – Jonathan Leffler Mar 19 '22 at 14:30
  • The `printf("path%d: %s\n", i,path);` after each character is *undefined behaviour* without a string terminator (as done just below in `else`). – Weather Vane Mar 19 '22 at 14:34
  • @WeatherVane: He could have a `memset()` above the `for` loop. – Joshua Mar 19 '22 at 14:34
  • @JonathanLeffler Yep but I'm doing this to control if the directory is already created or not – JamesR Mar 19 '22 at 14:35
  • Where and how are `name` and `path` and `j` initialized? Post complete code. – SGeorgiades Mar 19 '22 at 14:35
  • @SGeorgiades char name[256]; int i, j = 0; char path[256]; – JamesR Mar 19 '22 at 14:37
  • Also, it seems to me that this task would be much easier using `strtok` – SGeorgiades Mar 19 '22 at 14:37
  • `j` is not incremented in the code you've shown... which is why `path` is only ever a single character – SGeorgiades Mar 19 '22 at 14:39
  • @SGeorgiades you're right :( – JamesR Mar 19 '22 at 14:43
  • If you do it right, you should be fine. You can find out whether a file name represents a directory with [`stat()`](https://stackoverflow.com/a/3828537/15168). You can create a string containing `"dir2"` and create that directory if it doesn't exist. Then you can extend that string to `"dir2/dir3"` and create that directory if it doesn't exist. Rinse and repeat until you reach the end of the path. See also [How can I create a directory tree in C++/Linux?](https://stackoverflow.com/a/675193/15168) (but that answer is C code that can be called from C++). – Jonathan Leffler Mar 19 '22 at 14:52
  • In general, if your program uses `chdir()`, you have to be careful because if the user specifies file names relative the current directory when the program is invoked but you change directory elsewhere, you have a lot of work to do to make sure you still access the correct files. Note `fchdir()`. – Jonathan Leffler Mar 19 '22 at 14:53

1 Answers1

1

I think I found it.

                path[i] = '\0';

But path is built up using j as an indexer.

                path[j] = '\0';

Should be correct.

And you're missing your increment on j:

                path[j] = name[i];
                path[i+1] = '\0';

Should be:

                path[j++] = name[i];
                path[j+1] = '\0';

What's funny is it actually is faster to do this one component at a time with chdir(), but the probability that you have found this is remote. When you get a couple hundred directories deep you can measure it.

Joshua
  • 40,822
  • 8
  • 72
  • 132
  • Yep i knew that but I wanted to control if a directory of the path is already created or not idk if I can have that information in a simple way with chdir() – JamesR Mar 19 '22 at 14:43
  • I have another question, how can I access the flag errors of chdir()? If I check n is always -1 if a problem occurs, how can I check if a EACCES error occurs? – JamesR Mar 19 '22 at 14:48
  • @JamesR: `errno` – Joshua Mar 19 '22 at 14:49