在我正在处理的旧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");
在Windows系统控制面板中,ENV_ROOT的环境值设置为“c:\ RootDir”。但是当我运行程序时,我一直在FullFilePath中输入一个字符串,该字符串缺少冒号字符串以及根文件夹中的任何内容。它看起来像这样:“ c \ data \ Config.xml ”。
使用Visual Studio调试器我在传递GetEnvironmentVariable行后查看了EnvVarValue,它向我展示了一个似乎包含我期望的所有字符的数组,包括冒号。但是在将它分配给PathRoot之后,将鼠标移到PathRoot上只会显示C并向下钻取它会显示一些关于坏ptr的信息。正如我所指出的那样,find_first_of()调用找不到冒号char。当附加完成后,它只保留初始C并删除RootDir值的其余部分。
所以似乎有一些关于冒号字符构造函数混乱的冒号字符。是的,我可以通过多种方法解决这个问题,方法是将冒号从env变量中删除,然后在代码中添加它。但我更愿意找到一种方法让它从环境变量中正确读取和使用。
答案 0 :(得分:4)
您不能简单地将char*
投射到wchar_t*
(通过投射到LPWSTR
)并期望事情能够发挥作用。这两者基本上是不同的类型,在Windows中,它们表示不同的编码。
你显然有WinAPI定义集合,GetEnvironmentVariable
解析为GetEnvironmentVariableW
,它使用UTF-16对字符串进行编码。实际上,这意味着在内存中的每个ASCII字符后跟0
个字节。
然后你构造一个std::string
,所以它需要第一个0
字节(在char
索引1处)作为字符串终止符,所以你得到{{1} }。
您有几种选择:
使用"c"
和std::wstring
致电wchar_t EnvVarValue[1024];
(使用GetEnvironmentVariableA()
和ASCII)
使用char
并使用wcstombs
之类的内容将返回的值转换为wchar_t EnvVarValue[1024];
。
答案 1 :(得分:3)
您似乎正在构建具有宽字符功能(如您对LPWSTR
的演员表示)。这意味着EnvVarValue
中的字符串是宽字符字符串,您应该使用wchar_t
和std::wstring
代替。
我猜测GetEnvironmentVariable
调用后数组数组中的内容实际上是ASCII值0x43 0x00 0x3a 0x00 0x5c 0x00
等(这是"C:\"
的宽字符表示)。第一个零作为窄字符串的字符串终止符,这就是窄字符串PathRoot
仅包含'C'
的原因。
答案 2 :(得分:0)
问题可能是EnvVarValue不是wchar。尝试使用wchar_t和std ::wstrîng。