How to deepcopy `char *` to std::stringstream? - c++

Having char * and its int length how to deep copy it into stringstream?

Use std::stringstream::write(s, length);.
Note if the char* is null terminated operator<<() can be used instead and the length does not need to be supplied:
std::stringstream s;
const char* buf = "hello";
s << buf;

Shouldn't write fullfil your requirements?
http://www.cplusplus.com/reference/ostream/ostream/write/

You should read the doc and this one

Related

C++ stringstream string to function(test, char *test2)

Have a MySQL query function, that needs to take a string parameter.
Which looks like this:
cin >> user_string;
stringstream ss;
ss << "select * from " << user_string;
Function looks like this:
mysql_perform_query(MYSQL *connection, char *sql_query)
Tried to convert to ss.c_str(); or ss.str().c_str();
Does not work.
What would be the correct way to do this? Skip Stingstream and build char?
C++ Strings confuses me...
It's unusual that mysql_perform_query doesn't want a const char *.
If that's your code, change it to accept a const char * and your approach will work.
mysql_perform_query( connection, user_string.str().c_str() );
If you can't change that function signature, this will work*.
mysql_perform_query( connection, &user_string.str()[0] );
*It's guaranteed to work in C++11, and while not guaranteed in C++03, does work in all common implementations
The SQL interface probably requires a char const*. ss.str()
will give you a string, and ss.str().c_str() will give you
a char const* from that string.
To points, however (more style than anything):
unless you actually need the bidirectional capacities of
stringstream, it's probably preferable to use the simpler
ostringstream (which only does output), and
if all you're doing is concatenation, there's no point in
using streams at all, just use the + operator on the strings.
(You can also use + to concatenate a string and a string
literal.) Streams are really for formatting and parsing, and
are overkill (unnecessary added complexity) for simple
concatenation.
ss.str().c_str() would be correct if only your function was
mysql_perform_query(MYSQL *connection, const char *sql_query);
This is because c_str() returns const char *.
If you are able to change the mysql_perform_query function to const char * then I would do so. Otherwise you could consider doing a const_cast, const_cast<char*>(ss.str().c_str()).
In the unlikely event that mysql_perform_query really does modify the C string being passed to it then you will have to copy your string to a vector and pass a pointer to that instead.
string str = ss.str();
vector<char> tmp(str.begin(), str.end());
tmp.push_back('\0');
mysql_perform_query(connection, &tmp[0]);
ss.str().c_str() is a const char * not a char * that is required. I would copy ss.str().c_str() into a char * then pass it to the function.
stringstream has a str method that returns a std::string; std::string has a c_str() method that returns a pointer to a char.
mysql_perform_query(connection, ss.str().c_str());
You did do a proper search before posting your question, didn't you?

How to use Strtok for tokenizing a Const char*?

I have a const char* variable which may have a value like "OpenStack:OpenStack1". I want to tokenize this const char* using strtok where the delimiter(which is of a const char* type) is ":" . But the problem is strtok is of following type:
char * strtok ( char * str, const char * delimiters );
Which means I can't use const char* for the first input as it has to be char*. Could you say me how I can convert this const char* into char*?
Thank you.
Since strtok actually writes to your string, you need to make a writable copy of it to tokenize;
char* copy = strdup(myReadonlyString);
...tokenize copy...
free(copy);
Declare it as an array:
char tokenedStr[] = "OpenStack:OpenStack1";
if not possible, copy it to a char array.
You can make a copy of your non-modifiable string and then use strtok.
You can portably use malloc and strcpy to copy the string.

std::string to char*

I want to convert a std::string into a char* or char[] data type.
std::string str = "string";
char* chr = str;
Results in: “error: cannot convert ‘std::string’ to ‘char’ ...”.
What methods are there available to do this?
It won't automatically convert (thank god). You'll have to use the method c_str() to get the C string version.
std::string str = "string";
const char *cstr = str.c_str();
Note that it returns a const char *; you aren't allowed to change the C-style string returned by c_str(). If you want to process it you'll have to copy it first:
std::string str = "string";
char *cstr = new char[str.length() + 1];
strcpy(cstr, str.c_str());
// do stuff
delete [] cstr;
Or in modern C++:
std::vector<char> cstr(str.c_str(), str.c_str() + str.size() + 1);
More details here, and here but you can use
string str = "some string" ;
char *cstr = &str[0];
As of C++11, you can also use the str.data() member function, which returns char *
string str = "some string" ;
char *cstr = str.data();
If I'd need a mutable raw copy of a c++'s string contents, then I'd do this:
std::string str = "string";
char* chr = strdup(str.c_str());
and later:
free(chr);
So why don't I fiddle with std::vector or new[] like anyone else? Because when I need a mutable C-style raw char* string, then because I want to call C code which changes the string and C code deallocates stuff with free() and allocates with malloc() (strdup uses malloc). So if I pass my raw string to some function X written in C it might have a constraint on it's argument that it has to allocated on the heap (for example if the function might want to call realloc on the parameter). But it is highly unlikely that it would expect an argument allocated with (some user-redefined) new[]!
(This answer applies to C++98 only.)
Please, don't use a raw char*.
std::string str = "string";
std::vector<char> chars(str.c_str(), str.c_str() + str.size() + 1u);
// use &chars[0] as a char*
If you just want a C-style string representing the same content:
char const* ca = str.c_str();
If you want a C-style string with new contents, one way (given that you don't know the string size at compile-time) is dynamic allocation:
char* ca = new char[str.size()+1];
std::copy(str.begin(), str.end(), ca);
ca[str.size()] = '\0';
Don't forget to delete[] it later.
If you want a statically-allocated, limited-length array instead:
size_t const MAX = 80; // maximum number of chars
char ca[MAX] = {};
std::copy(str.begin(), (str.size() >= MAX ? str.begin() + MAX : str.end()), ca);
std::string doesn't implicitly convert to these types for the simple reason that needing to do this is usually a design smell. Make sure that you really need it.
If you definitely need a char*, the best way is probably:
vector<char> v(str.begin(), str.end());
char* ca = &v[0]; // pointer to start of vector
This would be better as a comment on bobobobo's answer, but I don't have the rep for that. It accomplishes the same thing but with better practices.
Although the other answers are useful, if you ever need to convert std::string to char* explicitly without const, const_cast is your friend.
std::string str = "string";
char* chr = const_cast<char*>(str.c_str());
Note that this will not give you a copy of the data; it will give you a pointer to the string. Thus, if you modify an element of chr, you'll modify str.
Assuming you just need a C-style string to pass as input:
std::string str = "string";
const char* chr = str.c_str();
To obtain a const char * from an std::string use the c_str() member function :
std::string str = "string";
const char* chr = str.c_str();
To obtain a non-const char * from an std::string you can use the data() member function which returns a non-const pointer since C++17 :
std::string str = "string";
char* chr = str.data();
For older versions of the language, you can use range construction to copy the string into a vector from which a non-const pointer can be obtained :
std::string str = "string";
std::vector<char> str_copy(str.c_str(), str.c_str() + str.size() + 1);
char* chr = str_copy.data();
But beware that this won't let you modify the string contained in str, only the copy's data can be changed this way. Note that it's specially important in older versions of the language to use c_str() here because back then std::string wasn't guaranteed to be null terminated until c_str() was called.
To be strictly pedantic, you cannot "convert a std::string into a char* or char[] data type."
As the other answers have shown, you can copy the content of the std::string to a char array, or make a const char* to the content of the std::string so that you can access it in a "C style".
If you're trying to change the content of the std::string, the std::string type has all of the methods to do anything you could possibly need to do to it.
If you're trying to pass it to some function which takes a char*, there's std::string::c_str().
Here is one more robust version from Protocol Buffer
char* string_as_array(string* str)
{
return str->empty() ? NULL : &*str->begin();
}
// test codes
std::string mystr("you are here");
char* pstr = string_as_array(&mystr);
cout << pstr << endl; // you are here
Conversion in OOP style
converter.hpp
class StringConverter {
public: static char * strToChar(std::string str);
};
converter.cpp
char * StringConverter::strToChar(std::string str)
{
return (char*)str.c_str();
}
usage
StringConverter::strToChar("converted string")
For completeness' sake, don't forget std::string::copy().
std::string str = "string";
const size_t MAX = 80;
char chrs[MAX];
str.copy(chrs, MAX);
std::string::copy() doesn't NUL terminate. If you need to ensure a NUL terminator for use in C string functions:
std::string str = "string";
const size_t MAX = 80;
char chrs[MAX];
memset(chrs, '\0', MAX);
str.copy(chrs, MAX-1);
You can make it using iterator.
std::string str = "string";
std::string::iterator p=str.begin();
char* chr = &(*p);
Good luck.
A safe version of orlp's char* answer using unique_ptr:
std::string str = "string";
auto cstr = std::make_unique<char[]>(str.length() + 1);
strcpy(cstr.get(), str.c_str());
char* result = strcpy((char*)malloc(str.length()+1), str.c_str());
Alternatively , you can use vectors to get a writable char* as demonstrated below;
//this handles memory manipulations and is more convenient
string str;
vector <char> writable (str.begin (), str.end) ;
writable .push_back ('\0');
char* cstring = &writable[0] //or &*writable.begin ()
//Goodluck
This will also work
std::string s;
std::cout<<"Enter the String";
std::getline(std::cin, s);
char *a=new char[s.size()+1];
a[s.size()]=0;
memcpy(a,s.c_str(),s.size());
std::cout<<a;
No body ever mentioned sprintf?
std::string s;
char * c;
sprintf(c, "%s", s.c_str());

Conversion of char * to string

Does anyone have an idea how to convert char* to string. Actually, I have a function which returns value as char* and now i need to store/copy std::string.
I have tried something like
char *sResult = (char*)malloc(1024);
std:string line;
line= line+ sResult
Thanks and regards,
Sam
How about
std::string line(szResult);
There is an implicit conversion from const char* to std::string(via nonexplicit constructor). So the following will all work (suppose ch is const char* or char*)
std::string s (ch);
std::string s = ch;
s = ch;
f(ch); //where f is declared to take std::string
etc
The std::string class has a constructor taking a const char *so you can do
char *foo;
/* .... initialize foo ... */
std::string some_string(foo);
std:string line;
line.append(sResult);
or
std::string line(sResult);
If you have a line of data that isn't necessarily a C-string, you use string's constructor
std::string s(sResult, sSize);
Try this: char* ptrToString = "wharever"; std::string szMyStdString = ptrToString
First of all you need to type to colons for
the scope specifier like so:
std::string line;
And then depending on the C library you are using the + operator might not
be overloaded to handle char* string so you should be better of
using:
line = line + std::string(sResult);
Though your implementation, should work if you fix the scope specifier,
in full-featured c++ standard library implementations like ms or gcc ones.

How do I convert a string to a char* in c++?

I have an error in my program: "could not convert from string to char*". How do I perform this conversion?
If you can settle for a const char*, you just need to call the c_str() method on it:
const char *mycharp = mystring.c_str();
If you really need a modifiable char*, you will need to make a copy of the string's buffer. A vector is an ideal way of handling this for you:
std::vector<char> v(mystring.length() + 1);
std::strcpy(&v[0], mystring.c_str());
char* pc = &v[0];
Invoke str.c_str() to get a const char*:
const char *pch = str.c_str();
Note that the resulting const char* is only valid until str is changed or destroyed.
However, if you really need a non-const, you probably shouldn't use std::string, as it wasn't designed to allow changing its underlying data behind its back. That said, you can get a pointer to its data by invoking &str[0] or &*str.begin().
The ugliness of this should be considered a feature. In C++98, std::string isn't even required to store its data in a contiguous chunk of memory, so this might explode into your face. I think has changed, but I cannot even remember whether this was for C++03 or the upcoming next version of the standard, C++1x.
If you need to do this, consider using a std::vector<char> instead. You can access its data the same way: &v[0] or &*v.begin().
//assume you have an std::string, str.
char* cstr = new char[str.length() +1];
strcpy(cstr, str.c_str());
//eventually, remember to delete cstr
delete[] cstr;
Use the c_str() method on a string object to get a const char* pointer. Warning: The returned pointer is no longer valid if the string object is modified or destroyed.
Since you wanted to go from a string to a char* (ie, not a const char*) you can do this BUT BEWARE: there be dragons here:
string foo = "foo";
char* foo_c = &foo[0];
If you try to modify the contents of the string, you're well and truly on your own.
If const char* is good for you then use this: myString.c_str()
If you really need char* and know for sure that char* WILL NOT CHANGE then you can use this: const_cast<char*>(myString.c_str())
If char* may change then you need to copy the string into something else and use that instead. That something else may be std::vector, or new char[], it depends on your needs.
std::string::c_str() returns a c-string with the same contents as the string object.
std::string str("Hello");
const char* cstr = str.c_str();