Is there a way to pass std :: string to a function that takes a char * and modifies its contents?

I am trying to get back to programming, especially console games. I heard that curses were good for this, so I found a curse textbook, and I delve into it. I use C ++, and naturally I wanted to use std :: string, but functions like getstr() only accept char *. Is there a way to pass a string as char *, or will I have to give up using C ++ strings?

+2
source share
6 answers

You can still use C ++ std::string , but you will need to copy the contents to the buffer ( std::vector<char> would be nice) and copy it when using functions that expect a char* rewritable buffer.

+8
source

The only C ++ containers that can be safely passed to functions that expect C-style variable arrays are std::vector (don't forget to resize() it or make it big enough from the start) and boost::array (or std::array with C ++ 11).

+5
source

It will be difficult to manage if the library changes the contents and length arbitrarily. You can try to use the existing C ++ shell on CURSES . Or this (kind of old ...).

NCURSES has built-in C ++ bindings . Not sure what you are using, but check this out.

+1
source

if you want to put a string in such a function, you can, of course, use c_str ();

 getstr(string.c_str()); 

in addition, std :: string also contains const char string :: data () , which returns a pointer to the first character in the current string (but not terminated by zero!).

but it is not possible to change this line (obtained in one of the following ways) in this function.

but you can do this:

  change_c-str(char* str, int size); //... string str = "foo"; char arr[str.size()+1]; strcpy(arr, str.c_str()); change_c-str(arr, str.size()); //this is valid as long as change_c-str won't put string which is longer than size 
0
source

and now a real but illegal answer. All the std :: string implementations I've ever used may well allow you to crack string data

 char *naughty = const_cast<char*>(myStr.c_str()); naughty[3] = 'f'; 

it works. However, you cannot change the length. Note that indexing off the line will cause Really Bad Things to happen, but then true with char * anyway

0
source

As others said, you should wrap the functions in a copy, and then return from the C-style buffer. This solution using a short life wrapper object makes it pretty elegant:

 using namespace std; class Wrap { public: Wrap(string &S,int Length):Buffer(Length),Orig(S) { //constructor copies the string to the buffer copy(Orig.begin(),Orig.end(),&Buffer[0]); cout<<"Construct\n"; } ~Wrap() { //destructor copies the buffer contents back to the string Orig=&Buffer[0]; cout<<"Destruct\n"; } operator char*() { return &Buffer[0]; } vector<char> Buffer; string &Orig; }; void Func(char *T) //a typical C-Style function that modifies the string { cout<<"Function\n"; *(T+1)='Q'; *(T+2)='Q'; } int main() { string X("Hiya"); Func(Wrap(X,20)); //Call the function with a wrapped string cout<<X; //output the modified string } 

This code outputs:

 Construct Function Destruct HQQa 

which demonstrates how and what it works. This does not solve the problem, which should indicate the length of the buffer, but it allows a function called to change the length and contents of the string (up to the specified buffer size).

0
source

All Articles