Search code examples
c++linuxc++11systemstd

Trying to pass string variables into std::system


My code:

std::string mail;
std::string password;
std::system("mkdir ~/.cache/pbt");
std::cout << "Enter your accounts mail" << std::endl;
std::cin >> mail;
std::cout << "Now enter your accounts password";
std::cin >> password;
std::system("perl zap2xml.pl -u " + mail + " -p " + password + " -o ~/.cache/pbt");

When I try to compile this code:

The compiler says

main.cpp:13:62: error: cannot convert ‘std::__cxx11::basic_string<char>’ to ‘const char*’
   13 | std::system("perl zap2xml.pl -u " + mail + " -p " + password + " -o ~/.cache/pbt");
      |             ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~^~~~~~~~~~~~~~~~~~~~
      |                                                              |
      |                                                              std::__cxx11::basic_string<char>
In file included from /usr/include/c++/9.2.0/cstdlib:75,
                 from /usr/include/c++/9.2.0/ext/string_conversions.h:41,
                 from /usr/include/c++/9.2.0/bits/basic_string.h:6493,
                 from /usr/include/c++/9.2.0/string:55,
                 from /usr/include/c++/9.2.0/bits/locale_classes.h:40,
                 from /usr/include/c++/9.2.0/bits/ios_base.h:41,
                 from /usr/include/c++/9.2.0/ios:42,
                 from /usr/include/c++/9.2.0/ostream:38,
                 from /usr/include/c++/9.2.0/iostream:39,
                 from main.cpp:1:
/usr/include/stdlib.h:784:32: note:   initializing argument 1 of ‘int system(const char*)’
  784 | extern int system (const char *__command) __wur;
      |                    ~~~~~~~~~~~~^~~~~~~~~

It looks like std::system can't read std::string variables and only can reads const char* , but there must be some way to do this.

How can I resolve this issue?


Solution

  • std::system() takes a const char* as input, but you are trying to pass it a std::string instead. std::string is not implicitly convertible to const char*, hence the compiler error. However, you can use the string's c_str() method to get a const char*, eg:

    std::string cmd = "perl zap2xml.pl -u '" + mail + "' -p '" + password + "' -o ~/.cache/pbt";
    std::system(cmd.c_str());
    

    Alternatively:

    std::system(("perl zap2xml.pl -u '" + mail + "' -p '" + password + "' -o ~/.cache/pbt").c_str());
    

    Note the mail and password strings are being wrapped inside of single quotes. This is because these two parameters can contain special characters or malicious code, and so should be escaped accordingly.