Reputation: 396
I have a vector of strings which was created from parsing a config file. All the strings should be in the format key=value
. I'd like to iterate over the vector, and use the putenv function to set an environment variable to the key-value pair.
The code:
for(auto it = settings.begin(); it != settings.end(); it++) {
try {
auto i = it - settings.begin();
cout << i << endl;
putenv(settings.at(i));
} catch (...) {
cout << "Config is not in the format key=value ... please correct" << endl;
}
}
This throws the error:
cannot convert ‘__gnu_cxx::__alloc_traits<std::allocator<std::basic_string<char> > >::value_type {aka std::basic_string<char>}’ to ‘char*’ for argument ‘1’ to ‘int putenv(char*)’
I'm very new to C++, and all these variable types and pointers are confusing me.
Upvotes: 1
Views: 158
Reputation:
The error is caused by your call to putenv(), which expects a pointer to char
's. Your vector contains C++ strings (std::string)...
You can try this:
for (auto setting : settings) {
// ... putenv() is inconsistent across compilers, so use setenv() instead...
std::string key = item.substr( 0, item.find_first_of( "=" ) ) ;
std::string val = item.substr( key.length()+1 ) ;
if ( setenv( key.c_str(), val.c_str(), 1 ) != 0 ) {
cerr << "setenv(" << key << ',' << val << ") has failed: " << strerror( errno ) << endl;
}
}
From what I've read, putenv
should be avoided in new code, and setenv
should be used, as it makes a copy of its arguments, regardless of compiler version.
(setenv
is in stdlib.h)
Upvotes: 0
Reputation: 17454
You're mixing C and C++ stuff.
std::string
.putenv
is an "old" function expecting a pointer to a char
buffer, i.e. a C-string.Fortunately, std::string
makes it easy to get one of those:
putenv(settings.at(i).c_str());
// ^^^^^^^^
However, there is still a problem there. putenv
takes "ownership" of the buffer you give it, and expects it to last "forever". Yours won't; it'll only be there until the std::string
is modified or destroyed. Not good enough!
Conventionally, we use C's strdup
here to allocate a copy of the char
buffer. It's then putenv
's (or the OS's) responsibility to free it later.
putenv(strdup(settings.at(i).c_str()));
// ^^^^^^^ ^
Since putenv
is not in the C or C++ standard, but is provided by POSIX, you should check the manpages for your operating system to make sure you're using it correctly.
Upvotes: 3