what is use of C_str() function in C/C++ - c++

Can anybody tell me what is the use of c_str() function in C/C++?.
In which case it is necessary to use it?.

When you want to use your string with C-functions
string s = "hello";
printf( "your string:%s", s.c_str() );

It is a C++ thing, not a C one.
A common use of c_str (from std::string) is precisely to convert a C++ std::string to a const char* C string, which is required by many many low level C functions (e.g. Posix system calls like stat, etc).

Generates a null-terminated sequence of characters (c-string) with the same content as the string object and returns it as a pointer to an array of characters.
There is a good example of its use here: http://www.cplusplus.com/reference/string/string/c_str/

I presume you're asking about string::c_str()? It's a method that returns a C string representation of the string object. You might need a C string representation to call an OS API, for example.

Related

converting a string to a c string

m working on some homework but don't even know where to start on this one. If you could can you throw me in the right direction. This is what i'm suppose to do
Write your own version of the str_c function that takes a C++ string as an argument (with the parameter set as a constant reference variable) and returns a pointer to the equivalent C-string. Be sure to test it with an appropriate driver.
There are different possibilities to write such a function.
First, take a look at the C++ reference for std::string, which is the starting point for your problem.
In the Iterator section on that page, you might find some methods which can help you to get the string character by character.
It can also help to read the documentation for the std::string::c_str method, you'd like to imitate: string::c_string. It's important to understand, how the system works with normal C-strings (char*):
Due to the fact, that a C-string has now length- or size-attribute, a trick is used to determine the end of the string: The last character in the string has to be a '\0'.
Make sure you understand, that a char* string can also be seen as array of characters (char[]). This might help you, when understanding and solving your problem.
as we know, C-string is null-terminated array of char. you can put char by char from std::string to an array of char, and then closed with '\0'. and remember a pointer to a char (char*) is also representation of array of char. you can use this concept

Qt - How to convert QString to char (NOT char*)

This seems like it should be a fairly simple thing to do, but I'm having a hard time figuring out how to do it. Basically I just have a QString object that will always be one character (specifically a letter) long, and I need to convert it to a char to set it to an object in my class of that type. I know how to make it char*, with QString("myTextHere").toStdString.c_str(), but the object that the value needs to be set to isn't char*, it's char. Is there a way to do this? Thanks!
I'm pretty sure I found a way to convert the value without getting the error about QCharRef, I found if I use the QString::at() function to get the first index instead of QString("myText")[0], and then use toAscii() on that value, it seems to work and produce the correct value I want. In other words, this is what I did:
char c = QString("A").at(0).toAscii();
If you claim that this returns a char*:
QString("myTextHere").toStdString.c_str();
Then obviously, this will get the first character, which would be char:
QString("myTextHere").toStdString.c_str()[0];
It may not look pretty, and probably there are better ways of getting the first character, but by definition, this code should (probably must) work.
Use the index operator to get the first character of the string:
QString("myTextHere").toStdString()[0]
However, there is no need to convert to std::string, so the following is a better idea:
The main problem is that QString is in UTF-16 and contains QChars, two-byte characters. If your character can be represented using latin-1 charset, you should use
char ch = QString("myTextHere")[0].latin1();
Otherwise you need a bigger type (NOTE: even this cuts non-BMP characters in half):
int i = QString("myTextHere")[0].unicode();
Like others have said, use QString::operator[]. Using this on a QString will return a QCharRef, a helper class that is equivalent to a QChar. Since QChar is meant to support unicode characters there is only one further specification. From QChar in qt documentation (4.7):
QChar provides constructors and cast operators that make it easy to
convert to and from traditional 8-bit chars. If you defined
QT_NO_CAST_FROM_ASCII and QT_NO_CAST_TO_ASCII, as explained in the
QString documentation, you will need to explicitly call fromAscii() or
fromLatin1(), or use QLatin1Char, to construct a QChar from an 8-bit
char, and you will need to call toAscii() or toLatin1() to get the
8-bit value back.
My Qt build will not allow
char c = QString("myTextHere")[0];
and instead I would use
char c = QString("myTextHere")[0].toAscii();
this worked for me in case you are getting error
error: reference to non-static member function must be called; did you
mean to call it with no arguments?
QString mystr = "mystring";
char myvar = mystr.toStdString().c_str()[0];

getline(cin,_string);

I know that getline(cin,_string); works perfectly
but this dosen't:
char* _chArr = new char;
getline(cin,_chArr);
Even this alson doesn't work:
char* _chArr = new char[30];
getline(cin,_chArr);
Isn't char* a string??
isn't char* is a string
No, it's a pointer to a char and that's that. The function std::getline does some cool stuff (extending the string and all) that can't be done easily on a char *.
Well think of it logically. the char* is just a pointer to a character type memory block. You have to assign it some amount of dynamic memory and then copy data into it using strcpy() or manually. Direct input is not supported in C++. Strings are in fact objects which contain size within themselves. They are designed by the experts in this industry, and they have provided the direct input and dynamic growth as in built functionality.
There is a differnce between string and cstring. Cstring is the char*.
No, C++ strings are not just character arrays, they are a full blown class, usually with quite a bit of extra stuff under the covers, over and above what a character array provides.

C++: Is it safe to move a jpeg around in memory using a std::string?

I have an external_jpeg_func() that takes jpeg data in a char array to do stuff with it. I am unable to modify this function. In order to provide it the char array, I do something like the following:
//what the funcs take as inputs
std::string my_get_jpeg();
void external_jpeg_func(const char* buf, unsigned int size);
int main ()
{
std::string myString = my_get_jpeg();
external_jpeg_func(myString.data(), myString.length() );
}
My question is: Is it safe to use a string to transport the char array around? Does jpeg (or perhaps any binary file format) be at risk of running into characters like '\0' and cause data loss?
My recommendation would be to use std::vector<char>, instead of std::string, in this case; the danger with std::string is that it provides a c_str() function and most developers assume that the contents of a std::string are NUL-terminated, even though std::string provides a size() function that can return a different value than what you would get by stopping at NUL. That said, as long as you are careful to always use the constructor that takes a size parameter, and you are careful not to pass the .c_str() to anything, then there is no problem with using a string here.
While there is no technical advantage to using a std::vector<char> over a std::string, I feel that it does a better job of communicating to other developers that the content is to be interpreted as an arbitrary byte sequence rather than NUL-terminated textual content. Therefore, I would choose the former for this added readability. That said, I have worked with plenty of code that uses std::string for storing arbitrary bytes. In fact, the C++ proto compiler generates such code (though, I should add, that I don't think this was a good choice for the readability reasons that I mentioned).
std::string does not treat null characters specially, unless you don't give it an explicit string length. So your code will work fine.
Although, in C++03, strings are technically not required to be stored in contiguous memory. Just about every std::string implementation you will find will in fact store them that way, but it is not technically required. C++11 rectifies this.
So, I would suggest you use a std::vector<char> in this case. std::string doesn't buy you anything over a std::vector<char>, and it's more explicit that this is an array of characters and not a possibly printable string.
I think it is better to use char array char[] or std::vector<char>. This is standard way to keep images. Of course, binary file may contain 0 characters.

Why this sprintf statement crashing? [duplicate]

This question already has answers here:
How to read and write a STL C++ string?
(3 answers)
Closed 4 years ago.
char filebuf[256];
path current = current_path();
std::cout<<"CurrentWorking "<<current<<endl;
string _UserDir = "TTiTraceLogs";
sprintf(filebuf,"%s/%s",current,_UserDir); ///crashing here
If I format only current, then it is ok.
sprintf(filebuf,"%s",current);
Output:
CurrentWorking D:/working/eclipse_projects/sadftp/CollectTTiTraceSept10_1009_174
_higher/xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx/Release
In the standard sprintf() function (and the other printf()-like functions), the %s specifier doesn't work with C++ stringss; it only works with C-style strings. Try _UserDir.c_str(), which gives you a const char * that points to the internal array of the string and can therefore be used with many C functions.
If current_path() returns something that is not a (possibly const) pointer to char or unsigned char, you need to convert that value too.
Is string actually std::string? And path a boost::filesystem::path? In that case, you should know that C library functions (like sprintf and printf) don't support C++ classes like std::string. That's only natural.
What you need to do is:
sprintf(filebuf, "%s%s", current.c_str(), _UserDir.c_str());
But a more elegant solution, if you're already using C++, is to either use std::stringstream or boost::format. As a bonus won't have to mess with allocating buffers on the stack and worrying that the result might be longer than the buffer (which may lead to buffer overruns and security exploits - sprintf() is probably the culprit behind many of those...).
std::stringstream
std::stringstream filebuf;
filebuf << current_path().c_str() << _UserDir;
std::string filename = filebuf.str();
boost::format
std::string filename = "%s%s" % current_path().c_str() % _UserDir;
By the way, if you just want to concatenate directories, the 'proper' way to do that with boost::filesystem::path would be:
boost::filesystem::path fullPath = current_path() / _UserDir;
Yes, the / operator is used for adding path components. They are separated by slashes after all, aren't they?
That being said, if you still choose, against all good advice, to use the old C library functions, please, for all that's good in the world, don't use sprintf(). Use the slightly-safer snprintf(), which takes the maximum buffer size as an argument.
Some of your code is unclear (e.g., what on earth is a path type?), but it looks like you're trying to print a std::string via a C-style string formatter (sprintf %s), which is totally invalid.
Look at std::stringstream. Also, for simple concatenation, std::string provides a + operator overload. So you could be doing simply:
current + "/" + whatever
sprintf only works with char*, you cannot use it with strings. Try _UserDir.c_str() and you should be fine.
What I don't understand is why your compiler doesn't complain. You can't pass non-POD types like std::string or boost::filepath as varargs; my compiler says that this will abort at runtime, and any compiler will know here that you're passing class types to a vararg. (Formally, it's undefined behavior, but unless the compiler defines it somehow as an extention, then there's no reason for it not to at least warn.)
current is not a char* pointer, it is a path so it might lead to complication
also, sprintf can't print to string variables like you are trying to do.
How long is current_path? Maybe strlen(current_path)+strlen(_UserDir)+2 > 256.
Since _UserDir is a C++ string, you'll need to get its C string to call sprintf(), which is a C function.
sprintf(filebuf,"%s/%s",current,_UserDir.c_str()); // gets C string
Also, what is a path? If it isn't like a typedef for char*, then you can't just sprintf() that either. It may be that operator<<() is overloaded for path, which is why the std::cout works.
%s indicates a C string. You have a C++ string. You need to call .c_str()
The reason of the crash has already been explained - I can only add one piece of advice - just ditch sprintf if possible and use string streams. It will make your code better. You will not have to worry about the length of the buffer or other errors like the one you encountered.