简体   繁体   中英

How to get the directory of a file from the full path in C

I'm trying to dynamically obtain the parent directory (let's say C:\some\dir ) from a file name I get in an argument (say C:\some\dir\file ), and put it in a char* . I already have the full path and file in a char* . How exactly would I do that in C?

I have some code but in my mind it's all garbled and I can't make any sense of it. How should I rework/rewrite this?

/* Gets parent directory of file being compiled */
    short SlashesAmount;
    short NamePosition;
    short NameLength;
    char* Pieces[SlashesAmount];
    char* SplitPath;
    short ByteNumber;
    short PieceNumber;
    char* ScriptDir;
    NameLength = strlen(File);

    //Dirty work
    SplitPath = strtok(File, "\");
    do {
        ByteNumber = 0;
        do {
            File[NamePosition] = CurrentPiece[ByteNumber];
            NamePosition++;
        } while(File[NamePosition] != '\n');
        PieceNumber++;
    } while(NamePosition < NameLength);

What you're looking for is dirname(3) . This is POSIX-only.

A Windows alternative would be _splitpath_s .

errno_t _splitpath_s(
   const char * path,
   char * drive,
   size_t driveNumberOfElements,
   char * dir,
   size_t dirNumberOfElements,
   char * fname,
   size_t nameNumberOfElements,
   char * ext, 
   size_t extNumberOfElements
);

Sample code (untested):

#include <stdlib.h>
const char* path = "C:\\some\\dir\\file";
char dir[256];

_splitpath_s(path,
    NULL, 0,             // Don't need drive
    dir, sizeof(dir),    // Just the directory
    NULL, 0,             // Don't need filename
    NULL, 0);           

You already have the full path of the file (for example: C:\some\dir\file.txt), just:
1. find the last slash by strrchr() : called p
2. copy from the beginning of the path to the p - 1 (do not include '/')
So the code will look like:

char *lastSlash = NULL;
char *parent = NULL;
lastSlash = strrchr(File, '\\'); // you need escape character
parent = strndup(File, strlen(File) - (lastSlash - 1));
int len = strlen(filepath);  
char* dir = malloc(len + 1);
strcpy(dir, filepath);
while (len > 0) {
   len--;
   if (dir[len] == '\\' || dir[len] == '/') {
      dir[len] = '\0';
      break;
   }
}

Don't have enough reputation to comment so add a answer here.

As Grijesh Chauhan commented in question, you can use strrchr() to get a shorter version of your original string.

However, the return value of strrchr() is char * , which SHOULD NOT be assigned to \0 that makes it points to nothing , instead, you can use * or [0] to modify it's first element to shorten the original string.

LIKE THIS:

strrchr(File, '\\')[0] = '\0'

// or this
*(strrchr(File, '\\') = '\0'

Great answer though, Grijesh should make it a answer :D

Here is a function that gets the full path and a buffer. it will update the buffer to the parent path. The function is checked. enjoy :)

/*
Use: Get parent path by full path
Input: full path, parent buffer
Output: None
*/
void getParent(char* path, char* parent)
{
    int parentLen;
    char* last = strrchr(path, '/');

    if (last != NULL) {

        parentLen = strlen(path) - strlen(last + 1);
        strncpy(parent, path, parentLen);
    }
}

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM