Reputation: 550
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!
Upvotes: 3
Views: 2377
Reputation: 1495
string is a class in c++ stl. c_str() is a member function of class string .
The signature is:
const _CharT* c_str() const { return _M_start; }
now, coming to printf, its signature is:
int printf ( const char * format, ... );
now, as long as you give it an argument that meets const char * format, it accepts it.
Upvotes: 0
Reputation: 726569
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.
Upvotes: 5
Reputation: 180585
Because printf()
has no idea what a std::string
is. The protypes for printf()
are
int printf( const char* format, ... );
int fprintf( std::FILE* stream, const char* format, ... );
int sprintf( char* buffer, const char* format, ... );
int snprintf( char* buffer, std::size_t buf_size, const char* format, ... );
The reason std::string
works with cout
is that std::string
provieds operator <<
which works with cout
Upvotes: 1
Reputation: 117866
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.
Upvotes: 2