Get drive letter from filename in Windows
Asked Answered
O

4

8

Is there a Windows API function to extract the drive letter from a Windows path such as

U:\path\to\file.txt
\\?\U:\path\to\file.txt

while correctly sorting out

relative\path\to\file.txt:alternate-stream    

etc?

Ordain answered 19/8, 2011 at 13:5 Comment(0)
C
13

PathGetDriveNumber returns 0 through 25 (corresponding to 'A' through 'Z') if the path has a drive letter, or -1 otherwise.

Cary answered 19/8, 2011 at 13:9 Comment(0)
R
5

Here is code that combines the accepted answer (thanks!) with PathBuildRoot to round out the solution

#include <Shlwapi.h>    // PathGetDriveNumber, PathBuildRoot
#pragma comment(lib, "Shlwapi.lib")

/** Returns the root drive of the specified file path, or empty string on error */
std::wstring GetRootDriveOfFilePath(const std::wstring &filePath)
{
// get drive #      http://msdn.microsoft.com/en-us/library/windows/desktop/bb773612(v=vs.85).aspx
int drvNbr = PathGetDriveNumber(filePath.c_str());

if (drvNbr == -1)   // fn returns -1 on error
    return L"";

wchar_t buff[4] = {};   // temp buffer for root 

// Turn drive number into root      http://msdn.microsoft.com/en-us/library/bb773567(v=vs.85)
PathBuildRoot(buff,drvNbr);

return std::wstring(buff);  
}
Registrar answered 16/6, 2012 at 2:1 Comment(3)
Thanks - two comments: you don't need to copy the array pointer, just use the array itself as the parameter to PathBuildRoot. And, if you want to initialize a static array, just use = {} because this is the general solution and works for all types and sizes.Ordain
@FelixDombek: fixed, thanks! This is cleaner, I like it. I'm still fairly new to C++, your feedback is appreciatedRegistrar
That's cool. Then you might be interested to know that you can (almost) always use buff to mean the same thing as &buff[0] for static arrays. Works for function calls, returns, etc. (see lysator.liu.se/c/c-faq/c-2.html, arrays decay into pointers in expressions except when the array is the operand of a sizeof or & operator which is not the case here)Ordain
O
3

Depending on your requirements, you might also want to consider GetVolumePathName to get the mount point, which may or may not be a drive letter.

Oxytocin answered 28/5, 2014 at 0:28 Comment(0)
G
0
#include <iostream>
#include <string>

using namespace std;

int main()
{    
    string aux;
    cin >> aux;
    int pos = aux.find(':', 0);
    cout << aux.substr(pos-1,1) << endl;
    return 0;
}
Geraldine answered 19/8, 2011 at 13:12 Comment(3)
Where's the Windows API function? :PIrreparable
@m0skit0: your function doesn't work if it's a relative path with an alternate NTFS stream ;)Ordain
I used the examples you provided since I'm not very experienced working with Windows :)Geraldine

© 2022 - 2024 — McMap. All rights reserved.