C++ 环境变量位于char*中,如何将其转换为std::string

C++ 环境变量位于char*中,如何将其转换为std::string,c++,winapi,cstring,C++,Winapi,Cstring,我正在使用GetEnvironmentStrings()在win32中检索环境变量。它返回一个字符* 我想在这个字符串(字符指针)中搜索一个特定的环境变量(是的,我知道我可以使用GetEnvironmentVariable(),但我这样做是因为我也想在控制台上打印所有的环境变量——我只是在摆弄而已) 因此,我想我会将char*转换为std::string并在其上使用find(我知道我也可以使用c_string find函数,但我更关心的是尝试将char*复制为std::string)。但是下面的

我正在使用
GetEnvironmentStrings()
在win32中检索环境变量。它返回一个
字符*

我想在这个字符串(字符指针)中搜索一个特定的环境变量(是的,我知道我可以使用
GetEnvironmentVariable()
,但我这样做是因为我也想在控制台上打印所有的环境变量——我只是在摆弄而已)

因此,我想我会将
char*
转换为std::string并在其上使用find(我知道我也可以使用c_string find函数,但我更关心的是尝试将
char*
复制为
std::string
)。但是下面的代码似乎没有将所有的
char*
复制到
std::string
(这让我觉得
char*
中有一个
\0
字符,但它实际上并不是结尾)


有没有办法将
char*
复制到
std::string
(我知道我可以使用
strcpy()
const char*
复制到字符串中,而不是
char*
)。

以下情况是否会导致任何问题

char* a = GetEnvironmentStrings();
string b;
b=a;
printf( "%s", b.c_str() );
sizeof(a)
在上述内容中,将返回
char*
的大小,即指针(通常为32或64位)。您在那里寻找函数
strlen
。实际上根本不需要:

std::string b(a);
应该足以获得第一个环境变量对。

当您说:

string b = string(a, sizeof(a));
你得到的是a的大小,这是一个指针,可能是4。因此,您将获得前4个字符。我不确定你到底想做什么,但你应该能够说:

string b( a );

您不想在此上下文中使用
sizeof()
,只需将值传递到构造函数中即可
char*
很容易变成
const char*
,您也不想使用
strcpy
printf

这是针对传统C字符串的,但是
GetEnvironmentStrings()
返回的格式有点奇怪,您可能需要手动插入它

const char* a = GetEnvironmentStrings();
int prev = 0;
std::vector<std::string> env_strings;
for(int i = 0; ; i++) {
    if (a[i] == '\0') {
        env_strings.push_back(std::string(a + prev, a + i));
        prev = i;
        if (a[i + 1] == '\0') {
            break;
        }
    }
}
for(int i = 0; i < env_strings.size(); i++) {
    std::cout << env_strings[i] << "\n";
}
const char*a=GetEnvironmentStrings();
int prev=0;
std::向量环境字符串;
对于(int i=0;i++){
如果(a[i]='\0'){
env_strings.push_back(std::string(a+prev,a+i));
prev=i;
如果(a[i+1]='\0'){
打破
}
}
}
对于(int i=0;istd::cout我假设您指的是Windows API函数。因此,针对nullptr测试结果并执行简单赋值:

char* env = ::GetEnvironmentStrings();
if (0 != env)
{
   std::string senv = env;
   // use senv to find variables
}
else
{
   // report problem or ignore
}

GetEnvironmentStrings()
的结果指向包含所有环境字符串的内存。与Puppy的解决方案类似,它将被放入字符串向量中,其中每个字符串只包含一个环境变量(
“key=value”

LPTCH a
将:

A=ABC\0X=XYZ\0\0
每个变量都以
'\0'
终止,最后完整的环境字符串(
a
)将以附加的
'\0'
终止

strlen
将返回第一次出现的终止字符
'\0'
的大小。最后一个字符串将始终为空

while ((std::size_t len = strlen(a)) > 0)
{
    env_strings.push_back(std::string(a, len));
    a += len + 1;
}
多字节字符 对于多字节字符,它也可以工作:

LPTCH a = GetEnvironmentStrings();
std::vector<std::wstring> env_strings;

while ((std::size_t len = wcslen(a)) > 0)
{
    env_strings.push_back(std::wstring(a, len));
    a += len + 1;
}

FreeEnvironmentStrings(a);
LPTCH a=GetEnvironmentStrings();
std::向量环境字符串;
而((标准::尺寸长度=wcslen(a))>0)
{
env_strings.push_back(std::wstring(a,len));
a+=len+1;
}
自由环境字符串(a);

检查文档中的GetEnvironmentStrings-这还不够。谢谢,但我已经尝试过了&它仍然打印出=::=这让我觉得每个环境变量的末尾都有一个\0字符,这就是为什么我会得到这么少的字符bit@Mack,是的,上面只会捕获第一个,对不起,我忘记了环境block布局。谁是f*试图将其作为一个完全相同的副本来关闭?这是一个完全不同的问题!@Xeo:哦,不,不是…使用的
getenv
/
GetEnvironmentVariable
函数不同,但结果是相同的…OP所要做的就是用
GetEnvironmentVariable>替换
getenv
调用
call.@rubenvb:Exception GetEnvironmentStrings()返回一个不可靠的格式,OP需要特定的帮助。您不能用
GetEnvironmentStrings()替换
GetEnvironmentStrings
。问题并不完全相同。毕竟他并没有试图学习如何做,他只是想知道为什么会发生这样的事情。呜呜,对不起,我还没有清醒到可以用我的“close”投票。我对std::string有了更多的了解,它会打印出来:=::=::\n谢谢我的理解,所以这一定是真的,环境变量的char*中充满了\0个字符。我采用了你的方法,但我认为我将使用c字符串函数strtok在\0处拆分它,而不是迭代每个字符characters@Mack:你不能那样做。
GetEnvironMyStords<代码>返回内存,您不允许写,并且<代码> Sttok不是线程安全的,无论如何它都是不安全的。使用McA:不要忘记,<代码> Strutok <代码>本身就是一个可怕的错误的事情。它是一个完整的单态机。@ MaC:哦,我认为C++不可能。t
strtok
不在第一个
\0
处停止,等待双精度
\0
。所有C字符串库都希望
\0
作为终止符-这就是为什么您需要自定义解析代码。如果没有环境变量(即“\0”),它能工作吗返回。您可以使用
std::string_view
避免为处理字符串而分配和复制字符串(例如,查找特定变量)。但在调用FreeEnvironmentStrings()之前,请复制需要保存的内容。
std::vector<std::string> env_strings;
LPTCH a = GetEnvironmentStrings();
while ((std::size_t len = strlen(a)) > 0)
{
    env_strings.push_back(std::string(a, len));
    a += len + 1;
}
LPTCH a = GetEnvironmentStrings();
std::vector<std::wstring> env_strings;

while ((std::size_t len = wcslen(a)) > 0)
{
    env_strings.push_back(std::wstring(a, len));
    a += len + 1;
}

FreeEnvironmentStrings(a);