2

I am now using C++ to program a robot using PROS. Pros has a print function, which is taking in a const char*. Now, I'm using lvgl to create my own screen, and I want to replicate the print function. Like the printf() functions, I want it to include variadic params to do the %d effect (so it converts all the %? to the corresponding values). The problem now is about the conversions between functions. I wanted to make a convert function to convert a string and the variadic params into a complete string. I need to input is a string which is like "hey" and I'm unsure what the type name should be. I need to be able to get size, search in it for %ds but I need the function to return a const char* to pass onto the lvgl to pring on the screen. I am having a bad time trying to convert a string into an const char* for the out put of the convert function.

Also, I tried using the input type as a char*, and when I input a string like "hello" is says a error [ISO C++11 does not allow conversion from string literal to 'char ' [-Wwritable-strings]]. But instead, when is use a const char, the error disappears. Anyone knows why?

Thanks everyone for your kind help!

Eden Cheung
  • 303
  • 2
  • 8
  • I would suggest you study the source code for functions like `printf` and `vsprintf`to learn how they work. – David Schwartz Jul 15 '19 at 02:32
  • Here is the print function: https://code.woboq.org/userspace/glibc/stdio-common/printf.c.html They look easy, and i dont even see a part that will handle the "%d"s. – Eden Cheung Jul 15 '19 at 02:39
  • @EdenCheung It's handled within `__vfprintf_internal`. You can see it here: https://github.com/lattera/glibc/blob/master/stdio-common/vfprintf.c It's not easy. – eerorika Jul 15 '19 at 02:51
  • I cant find _vfprintf_internal... con you explain me abit of its logic? Thanks a lot – Eden Cheung Jul 15 '19 at 02:55
  • 1
    Possible duplicate of [How to convert a std::string to const char\* or char\*?](https://stackoverflow.com/questions/347949/how-to-convert-a-stdstring-to-const-char-or-char) –  Jul 15 '19 at 03:51
  • Also, see [my answer](https://stackoverflow.com/a/56658537/10957435) for a quick guide on the types of strings in C++. –  Jul 15 '19 at 03:55

2 Answers2

3

char* and const char* are two flavours of the same thing: C-style strings. These are a series of bytes with a NUL terminator (0-byte). To use these you need to use the C library functions like strdup, strlen and so on. These must be used very carefully as missing out on the terminator, which is all too easy to do by accident, can result in huge problems in the form of buffer-overflow bugs.

std::string is how strings are represented in C++. They're a lot more capable, they can support "wide" characters, or variable length character sets like UTF-8. As there's no NUL terminator in these, they can't be overflowed and are really quite safe to use. Memory allocation is handled by the Standard Library without you having to pay much attention to it.

You can convert back and forth as necessary, but it's usually best to stick to std::string inside of C++ as much as you can.

To convert from C++ to C:

 std::string cppstring("test");
 const char* c_string = cppstring.c_str();

To convert from C to C++:

 const char* c_string = "test";
 std::string cppstring(c_string);

Note you can convert from char* (mutable) to const char* (immutable) but not in reverse. Sometimes things are flagged const because you're not allowed to change them, or that changing them would cause huge problems.

You don't really have to "convert" though, you just use char* as you would const char*.

tadman
  • 208,517
  • 23
  • 234
  • 262
2
std::string A = "hello"; //< assignment from char* to string
const char* const B = A.c_str(); //< call c_str() method to access the C string
std::string C = B; //< assignment works just fine (with allocation though!)

printf("%s", C.c_str()); //< pass to printf via %s & c_str() method
robthebloke
  • 9,331
  • 9
  • 12
  • 2
    Be _very careful_ storing the pointer obtained via `std::string::c_str()`. I have encountered and fixed many instances where even experienced programmers mistakenly store this pointer from a string that goes out of scope: most commonly when called directly from a function that returned a `std::string` rvalue (e.g. `const char* time_bomb = get_some_string().c_str()`) – paddy Jul 15 '19 at 03:47