Search code examples
c++data-structurescastingqueue

C++: Cannot convert string to char*?


I'm trying to print the first item (top item) of a Deque in C++ with the following piece of code:

#include <queue>
#include <deque>
#include <string>

using namespace std;

int main(int argc, char *argv[]){
    deque<string> commandHistory;

    for (int i = 0; i < 2; i++) {
        commandHistory.push_back("asdf");
    }

    printf(commandHistory.at(1));
    return 0;
}

However, I get an error in the printf statement:

error: cannot convert ‘__gnu_cxx::__alloc_traitsstd::allocator<std::__cxx11::basic_string<char

, std::__cxx11::basic_string >::value_type’ {aka ‘std::__cxx11::basic_string’} to ‘const char*’

However, I cannot cast commandHistory.at(1) to a const char* like so:

printf((const char*) commandHistory.at(1));

Solution

  • Eventhough your question is marked both C and C++, I'd remove the C tag since your code is more C++ than C.

    The documentation for printf is here: https://en.cppreference.com/w/cpp/io/c/fprintf

    The gist of that function is that it takes at least 1 param: the so called format string, which as the signature says, is a const char*.

    char * and std::string are totally different types. std::string is a class and char * is just a pointer to a builtin type. Your std::deque contains std::string objects.

    Conveniently, std::string offers a conversion function to const char* for exactly these cases.

    A working snippet would thus be:

    // looks like you were missing cstdio
    #include <cstdio>
    #include <deque>
    #include <string>
    using namespace std;
    
    int main(int argc, char *argv[]){
        deque<string> commandHistory;
    
        for (int i = 0; i < 2; i++) {
            commandHistory.push_back("asdf");
        }
        // note the `c_str` method call to get a c-style string from a std::string
        printf(commandHistory.at(1).c_str());
        return 0;
    }
    

    Like the compiler says, you can't convert (with static_cast) a std::string to a char*, but you can obtain that desired const char* with .c_str().

    As other mentioned, you could also include iostream and use std::cout which knows what to do (by overloading) with each type (const char*, std::string, int, ...) and can also be used with your own types.

    EDIT: cleaner/clearer code/explanations.