当我从char []变为字符串时,为什么我的冒号字符会消失?

时间:2013-12-27 16:15:28

标签: c++

在我正在处理的旧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变量中删除,然后在代码中添加它。但我更愿意找到一种方法让它从环境变量中正确读取和使用。

3 个答案:

答案 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_tstd::wstring代替。

我猜测GetEnvironmentVariable调用后数组数组中的内容实际上是ASCII值0x43 0x00 0x3a 0x00 0x5c 0x00等(这是"C:\"的宽字符表示)。第一个零作为窄字符串的字符串终止符,这就是窄字符串PathRoot仅包含'C'的原因。

答案 2 :(得分:0)

问题可能是EnvVarValue不是wchar。尝试使用wchar_t和std ::wstrîng。