在我正在处理的旧 Windows 应用程序中,我需要从环境变量获取路径,然后附加到它以构建文件路径。所以代码看起来像这样:
static std::string PathRoot; // Private variable stored in class' header file
char EnvVarValue[1024];
if (! GetEnvironmentVariable(L"ENV_ROOT", (LPWSTR) EnvVarValue, 1024))
{
cout << "Could not retrieve the ROOT env variable" << endl;
return;
}
else
{
PathRoot = EnvVarValue;
}
// Added just for testing purposes - Returning -1
int foundAt = PathRoot.find_first_of(':');
std::string FullFilePath = PathRoot;
FullFilePath.append("\\data\\Config.xml");
ENV_ROOT 的环境值在 Windows 系统控制面板中设置为“c:\RootDir”。但是当我运行程序时,我总是以 FullFilePath 中的字符串结尾,该字符串缺少冒号字符以及根文件夹中后面的任何内容。它看起来像这样:“c\data\Config.xml”。
通过 GetEnvironmentVariable 行后,我使用 Visual Studio 调试器查看了 EnvVarValue,它向我显示了一个数组,该数组似乎包含我期望的所有字符,包括冒号。但是在它被分配给 PathRoot 之后,将鼠标悬停在 PathRoot 上只会显示 C 并向下钻取它会说一些关于错误 ptr 的信息。正如我所指出的, find_first_of() 调用没有找到冒号字符。当附加完成时,它只保留初始 C 并删除 RootDir 值的其余部分。
所以冒号字符似乎有一些东西混淆了字符串构造函数。是的,我可以通过多种方法解决此问题,方法是将冒号从 env 变量中删除并稍后将其添加到代码中。但我更愿意找到一种方法,让它按原样从环境变量中正确读取和使用。
最佳答案
您不能简单地将 char*
转换为 wchar_t*
(通过转换为 LPWSTR
)并期望一切正常。两者是根本不同的类型,在 Windows 中,它们表示不同的编码。
您显然已将 WinAPI 定义设置为 GetEnvironmentVariable
解析为 GetEnvironmentVariableW
,它使用 UTF-16 对字符串进行编码。实际上,这意味着 0
字节跟在内存中的每个 ASCII 字符之后。
然后您从中构造一个 std::string
,因此它将第一个 0
字节(在 char
索引 1)作为字符串终止符,所以你得到的只是 "c"
。
您有多种选择:
使用
std::wstring
和wchar_t EnvVarValue[1024];
调用
GetEnvironmentVariableA()
(使用char
和 ASCII)使用
wchar_t EnvVarValue[1024];
并使用wcstombs
之类的东西将返回值转换为std::string
.
关于c++ - 当我从 char[] 转到 string 时,为什么我的冒号字符消失了?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/20803931/