如何用 GetWindowsDirectoryA 返回的结果具体化一个字符串?

How to concrete a string with GetWindowsDirectoryA returned result?

我正在使用此 GetWindowsDirectoryA Windows API 函数来获取 Windows 文件夹的位置。

#include <iostream>
#include <string>
#include <vector>

#ifdef __WIN32
#include <fcntl.h>
#include <io.h>
#include <Windows.h>
#include <sysinfoapi.h>
#endif

std::string GetOSFolder() {
        std::vector<char> buffer(MAX_PATH + 1);

        GetWindowsDirectoryA(buffer.data(), MAX_PATH);

        std::string windowsRoot{ buffer.data(), buffer.size() };

        return windowsRoot + "/SomeFolder";
}

int main() {
    std::cout << GetOSFolder() << "\n";
}

我想用返回的 Windows 文件夹字符串结果具体化一个文件夹名称。

windowsRoot + "/SomeFolder"

以上尝试产生以下字符串,

C:\Windows

                                   /SomeFolder

这似乎是因为缓冲区大小设置为 MAX_PATH,这比实际字符串大。

有没有办法从具有实际字符串大小的缓冲区构造字符串?

你可以用路径初始化字符串,你甚至不需要知道大小(如评论部分所述,return由 GetWindowsDirectoryA 编辑),但这是明智的使用它,因为它确实优化了 std::string 初始化。

示例:

std::string GetOSFolder() {

    char buffer[MAX_PATH + 1];
   const auto size = GetWindowsDirectoryA(buffer, MAX_PATH);
    if (size) {
        return std::string(buffer, size).append("/SomeFolder");
    }
    return ""; // or however you want to handle the error
}

int main() {

    std::cout << GetOSFolder() << "\n";
}

或者您可以避免缓冲区的第二个变量,但您必须调整原始缓冲区的大小:

std::string GetOSFolder() {

    std::string buffer(MAX_PATH + 1, 0);
    auto result = GetWindowsDirectoryA(buffer.data(), MAX_PATH); // or &buffer[0] prior to C++17
    if (result) {
        buffer.resize(result);
        return buffer.append("/SomeFolder");
    }
    return buffer; // will be an empty string if API call fails
}

现在,如果您想避免调整大小,您仍然可以使用一些技巧:

std::string GetOSFolder() {

    const auto size = GetWindowsDirectoryA(nullptr , 0);
    if (size) {
        std::string buffer(size, 0);
        const auto result = GetWindowsDirectoryA(buffer.data(), MAX_PATH); // or &buffer[0] prior to C++17
        if (result) {
            return buffer.append("\OtherPath");
        }
    }
    return "";
}

在这里调用 GetWindowsDirectoryA 两次,第一次知道缓冲区所需的大小,第二次实际检索路径。

请注意,在最后一个选项中,第一次调用将 return 带有空终止符的字符串的长度,而第二次调用将仅 return 不包含空终止符的字符串的长度对于这种类型的调用,WIN32 中的典型字节 API,这是一个众所周知的模式。