Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

why string has to be converted to c_str (c string) when passing to printf?

Tags:

c++

I am new to C++ and I know I shouldn't be using printf in c++ while I have cout but this was for experiment sake. My Question here is Why we have to convert a string to c_str (c string) while passing to printf in c++ while it works fine without converting in cout. Below is my code

#include<iostream>
#include<stdio.h>
using namespace std;


class A{
int i;
string str;
public:
    A (int value, const string & s) : i(value), str(s){};// constructor
    // setters
    void setvalue(int value) {i = value;}
    void setstr(const string & s) {str = s;}
    //geters
    int get_value() {return i;}
    string get_str() {return str;}

    const char *get_str_cstr() {return str.c_str();}// I didn't get why we have to declare constant


};

int main(){
// new code
A obj1 = {11, "Jill"};

cout<<"value is : "<<obj1.get_value()<<" string is "<<obj1.get_str()<<endl;

// Now we wil change the values in A
obj1.setvalue(2);
obj1.setstr("Jack");
cout<<"value after change is : "<<obj1.get_value()<<" string after change is "<<obj1.get_str()<<endl;

// now we will use printf where get_str dosen't not work


//Error: for below commented printf function
/*In function 'int main()':|
error: cannot pass objects of non-trivially-copyable type 'std::string {aka class std::basic_string<char>}' through '...'|
||=== Build finished: 1 errors, 0 warnings (0 minutes, 0 seconds) ===|
*/

//printf("Value is %d and String is %s",obj1.get_value(),obj1.get_str());

// hence we declare a new char * get_str_cstr to make it work in printf;

printf("Value is %d and String is %s",obj1.get_value(),obj1.get_str_cstr());

return 0;}

I have also provided the error in program comments. Thank you!

like image 617
VoidZero Avatar asked Jan 26 '26 17:01

VoidZero


2 Answers

printf comes from C library, which predates objects, templates, and function overloading. When you specify %s format, the function takes an address of a null-terminated character sequence, and prints it. printf has no idea where the string comes from. In fact, it has no idea of its parameter types, because it uses variable-length parameter list feature.

std::string is a C++ string. Calling c_str() on it produces a pointer to the beginning of a C string, which is suitable for passing to printf and other functions expecting a C string.

cout, on the other hand, has been built with classes and overloading in mind. There is a special overload for operator << for std::string, which lets cout and other output streams extract characters from a C++ string.

like image 137
Sergey Kalinichenko Avatar answered Jan 28 '26 06:01

Sergey Kalinichenko


printf is originally from C, which does not have std::string, so the analogous argument type is const char* which is what you get when you call .c_str()

The reason std::cout works with std::string is because operator<< is defined for that class.

like image 36
Cory Kramer Avatar answered Jan 28 '26 06:01

Cory Kramer



Donate For Us

If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!