0

For an application that I'm writing, I have a string type variable that I want to display within an ncurses window:

#include <iostream>
#include <ncurses.h>
#include <string>

int main(){
  std::string mystring = "A sample string\n";

  // Entering the ncurses window
  initscr();
  printw(mystring);
  getch();
  endwin();

}

which throws the following error at compilation:

test_app.cpp: In function ‘int main()’:
test_app.cpp:12:18: error: cannot convert ‘std::__cxx11::string {aka std::__cxx11::basic_string<char>}’ to ‘const char*’ for argument ‘1’ to ‘int printw(const char*, ...)’
   printw(mystring);

Where am I going wrong? How can I rectify this?

Karthik
  • 29
  • 4
  • The message is quite clear: You are attempting to pass a `std::string` (i.e. a `basic_string` object), to a function that expects a pointer to const char. See the linked duplicate, which advises you to pass `mystring.c_str()`. – nanofarad Jul 13 '19 at 23:30
  • 1
    Thanks for that information. A follow up question - how then does a string that's natively passed to the `printw` function get converted to a pointer to const char? I.e., how does the call `printw("this is a string")` satisfy the function definition? EDIT: Sorry, I see that @alex-hodges answered this exact question. Thanks! – Karthik Jul 14 '19 at 22:20

1 Answers1

2

Some key concepts in c++:

A string literal declaration (aka "this is a string literal") has a type const char[N], where N is the size of the string, including the null terminator.

std::string != const char[]

However, a std::string can be constructed with a const char[] using this constructor (found here):

basic_string( const CharT* s,
              const Allocator& alloc = Allocator() );

Where CharT is your implementation specific char equivalent.

Now, notice how printw takes a const char*. You aren't passing a const char * to printw, you're passing a std::string, and they aren't implicitly convertible to a const char *.

We have two options to solve your problem...

1) Store the string as a char[] (aka char *):

#include <iostream>
#include <ncurses.h>
#include <string>

int main(){
  char mystring[] = "A sample string\n"; // Can decay to a char * implicitly.

  // Entering the ncurses window
  initscr();
  printw(mystring);
  getch();
  endwin();
}

2) Get a representation of the std::string as a char *:

#include <iostream>
#include <ncurses.h>
#include <string>

int main(){
  std::string mystring = "A sample string\n";

  // Entering the ncurses window
  initscr();
  // Since c++ 11, mystring.data() is required to return a null-terminated char *.
  // If c++ version < c++11, use mystring.c_str().
  printw(mystring.data());  
  getch();
  endwin();
}
Alex Hodges
  • 607
  • 1
  • 5
  • 9
  • You should always use `c_str()` in this case. It clarifies the intent. You intend to use C string version of this string, not as data. – Hatted Rooster Jul 14 '19 at 00:31
  • @SombreroChicken Since c++11, c_str() and data() are equivalent. The intent is identically clarified in each case. – Alex Hodges Jul 14 '19 at 00:52