开发者

Environment Variables are in a char* how to get it to a std::string

开发者 https://www.devze.com 2023-03-12 22:18 出处:网络
I am retrieving the environment variables in win32 using GetEnvironmentStrings(). It returns a char*.

I am retrieving the environment variables in win32 using GetEnvironmentStrings(). It returns a char*.

I want to search this string(char pointer) for a specific environmental variable (yes I know I can use GetEnvironmentVariable() but I am doing it this way because I also开发者_如何转开发 want to print all the environment variables on the console aswell - I am just fiddling around).

So I thought I would convert the char* to an std::string & use find on it (I know I can also use a c_string find function but I am more concerned about trying to copy a char* into a std::string). But the following code seems to not copy all of the char* into the std::string (it makes me think there is a \0 character in the char* but its not actually the end).

char* a = GetEnvironmentStrings();
string b = string(a, sizeof(a));
printf( "%s", b.c_str() );  // prints =::= 

Is there a way to copy a char* into a std::string (I know I can use strcpy() to copy a const char* into a string but not a char*).


You do not want to use sizeof() in this context- you can just pass the value into the constructor. char* trivially becomes const char* and you don't want to use strcpy or printf either.

That's for conventional C-strings- however GetEnvironmentStrings() returns a bit of a strange format and you will probably need to insert it manually.

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";
}


sizeof(a) in what you have above will return the size of char*, i.e. a pointer (32 or 64bits usually). You were looking for function strlen there. And it's not actually required at all:

std::string b(a);

should be enough to get the first environment variable pair.


The result of GetEnvironmentStrings() points to memory containing all environment strings. Similar to the solution of Puppy it will be put into a vector of string, where each string contains just one environment variable ("key=value")

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

As example we will have 2 environment variables defined:

"A=ABC"
"X=XYZ"

LPTCH a will be:

A=ABC\0X=XYZ\0\0

Each variable is '\0' - terminated and finally the complete environment string (a) will be terminated with an additional '\0'.

strlen will return the size to the first occurrence of the termination character '\0'. The last string will always be empty.

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

Multi-byte character

For multi-byte characters it will work as well:

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);


Does the following causes any problems?

char* a = GetEnvironmentStrings();
string b;
b=a;
printf( "%s", b.c_str() );


When you say:

string b = string(a, sizeof(a));

you are getting the size of a, which is a pointer and is probably 4. So you will get the first 4 characters. I'm not sure what you are really trying to do, but you should be able just to say:

string b( a );


char* a = ...;
string str(a);
string b;
b = a;


I assume you mean the Windows API GetEnvironmentStrings function. So, test the result against nullptr and perform simple assignment:

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

精彩评论

暂无评论...
验证码 换一张
取 消