How to convert a char* pointer into a C++ string? - c++

I have a C++ string. I need to pass this string to a function accepting a char* parameter (for example - strchr()).
a) How do I get that pointer?
b) Is there some function equivalent to strschr() that works for C++ strings?

To get the C string equivalent of
the C++ string object use c_str
function.
To locate the first occurence of a
char in a string object use
find_first_of function.
Example:
string s = "abc";
// call to strlen expects char *
cout<<strlen(s.c_str()); // prints 3
// on failure find_first_of return string::npos
if(s.find_first_of('a') != string::npos)
cout<<s<<" has an a"<<endl;
else
cout<<s<<" has no a"<<endl;
Note: I gave the strlen just an example of a function that takes char*.

Surprisingly, std:;string has far, far more capabilities than C-style strings. You probably want the find_first_of() method. In general, if you find yourself using the strxxx() functions on C++ std::strings, you are almost certainly doing something wrong.
Like much of the C++ Standard Library, the string class is a complex beast. To make the most of it, you really need a good reference book. I recommend The C++ Standard Library, by Nicolai Josuttis.

You can't get a char* from a string
string does not allow you free access to its internal buffer.
The closest you can get is a const char* using .c_str() if you want it null terminated or .data() if it doesn't have to be null terminated.
You can then cast the pointer returned by these functions to char* but you do this on your own risk. That being said this is a relatively safe cast to make as long as you make sure you're not changing the string. If you changed it then the pointer you got from c_str() may no longer be valid.
This code:
string str("Hello World!");
char* sp = (char*)str.c_str();
sp[5] = 'K';
is probably ok
However this:
string str("Hello World!");
char* sp = (char*)str.c_str();
str = "Chaged string";
sp[5] = 'K';
is most definitely not ok.

If you just want to assign a string literal to pw, you can do it like
char *pw = "Hello world";
If you have a C++ std::string object, the value of which you want to assign to pw, you can do it like
char *pw = some_string.c_str()
However, the value that pw points to will only be valid for the life time of some_string.
More here :
How to assign a string to char *pw in c++
GoodLUCK!!

std::string yourString("just an example");
char* charPtr = new char[yourString.size()+1];
strcpy(charPtr, yourString.c_str());

If str in your string use str.c_str() method to get the char* inside it.

Perhaps this exmaple will help you
#include <iostream>
#include <string>
using namespace std;
int main ()
{
string str ("Replace the vowels in this sentence by asterisks.");
size_t found;
found=str.find_first_of("aeiou");
while (found!=string::npos)
{
str[found]='*';
found=str.find_first_of("aeiou",found+1);
}
cout << str << endl;
return 0;
}

The C++ Standard provides two member functions of claass std::basic_string that return pointer to the first element of the string. They are c_str() and data(). But the both return const char *, So you may not use them with a function that has parameter of type char *.
As for function strchr then its first parameter is const char *. So you may use c_str() and data() with this function. However it is much better to use member function find()of class sttd::basic_string instead of strchr.

Related

How can I convert const char* to string and then back to char*?

I'm just starting c++ and am having difficulty understanding const char*. I'm trying to convert the input in the method to string, and then change the strings to add hyphens where I want and ultimately take that string and convert it back to char* to return. So far when I try this it gives me a bus error 10.
char* getHyphen(const char* input){
string vowels [12] = {"A","E","I","O","U","Y","a","e","i","o","u","y"};
//convert char* to string
string a;
int i = 0;
while(input != '\0'){
a += input[i];
input++;
i++;
}
//convert a string to char*
return NULL;
}
A: The std::string class has a constructor that takes a char const*, so you simply create an instance to do your conversion.
B: Instances of std::string have a c_str() member function that returns a char const* that you can use to convert back to char const*.
auto my_cstr = "Hello"; // A
std::string s(my_cstr); // A
// ... modify 's' ...
auto back_to_cstr = s.c_str(); // B
First of all, you don't need all of that code to construct a std::string from the input. You can just use:
string a(input);
As far as returning a new char*, you can use:
return strdup(a.c_str()); // strdup is a non-standard function but it
// can be easily implemented if necessary.
Make sure to deallocate the returned value.
It will be better to just return a std::string so the users of your function don't have to worry about memory allocation/deallocation.
std::string getHyphen(const char* input){
Don't use char*. Use std::string, like all other here are telling you. This will eliminate all such problems.
However, for the sake of completeness and because you want to understand the background, let's analyse what is going on.
while(input != '\0'){
You probably mean:
while(*input != '\0') {
Your code compares the input pointer itself to \0, i.e. it checks for a null-pointer, which is due to the unfortunate automatic conversion from a \0 char. If you tried to compare with, say, 'x' or 'a', then you would get a compilation error instead of runtime crashes.
You want to dereference the pointer via *input to get to the char pointed to.
a += input[i];
input++;
i++;
This will also not work. You increment the input pointer, yet with [i] you advance even further. For example, if input has been incremented three times, then input[3] will be the 7th character of the original array passed into the function, not the 4th one. This eventually results in undefined behaviour when you leave the bounds of the array. Undefined behaviour can also be the "bus error 10" you mention.
Replace with:
a += *input;
input++;
i++;
(Actually, now that i is not used any longer, you can remove it altogether.)
And let me repeat it once again: Do not use char*. Use std::string.
Change your function declaration from
char* getHyphen(const char* input)
to
auto hyphenated( string const& input )
-> string
and avoid all the problems of conversion to char const* and back.
That said, you can construct a std::string from a char_const* as follows:
string( "Blah" )
and you get back a temporary char const* by using the c_str method.
Do note that the result of c_str is only valid as long as the original string instance exists and is not modified. For example, applying c_str to a local string and returning that result, yields Undefined Behavior and is not a good idea. If you absolutely must return a char* or char const*, allocate an array with new and copy the string data over with strcpy, like this: return strcpy( new char[s.length()+1], s.c_str() ), where the +1 is to accomodate a terminating zero-byte.

Is it safe to ever cast the result of string's c_str to a char*?

I'm in c++ and i'm using a c library which has an api which accepts a char *. It doesn't accept a const char *, even though the data in the char * will not be modified.
Is it safe to get the result of c_str() and cast it to a 'char *' for use with this api?
string str = "mydata";
char * cstr = const_cast<char*>(str.c_str());
c_api_lib_func(cstr);
Yes, it's safe as long as the function you're passing it to does not attempt to modify the contents of the string.
You can even avoid the const_cast using
c_api_lib_func(&str[0]);
Note that this is technically not safe with a pre-C++11 compiler because std::string was not required to have contiguous storage for it's internal buffer.
Using &str[0], the function may even modify the contents of the string's internal buffer as long as it leaves the terminating NULL character alone.
As long as you treat is as strictly read-only, it shouldn't do any harm.
it is not safe
this code outputs dydata
#include <iostream>
using namespace std;
int main()
{
string str = "mydata";
char * cstr = const_cast<char*>(str.c_str());
cstr[0] ='d';
cout <<str << endl;
return 0;
}

What is the use of the c_str() function?

I understand c_str converts a string, that may or may not be null-terminated, to a null-terminated string.
Is this true? Can you give some examples?
c_str returns a const char* that points to a null-terminated string (i.e., a C-style string). It is useful when you want to pass the "contents"¹ of an std::string to a function that expects to work with a C-style string.
For example, consider this code:
std::string string("Hello, World!");
std::size_t pos1 = string.find_first_of('w');
std::size_t pos2 = static_cast<std::size_t>(std::strchr(string.c_str(), 'w') - string.c_str());
if (pos1 == pos2) {
std::printf("Both ways give the same result.\n");
}
See it in action.
Notes:
¹ This is not entirely true because an std::string (unlike a C string) can contain the \0 character. If it does, the code that receives the return value of c_str() will be fooled into thinking that the string is shorter than it really is, since it will interpret \0 as the end of the string.
In C++, you define your strings as
std::string MyString;
instead of
char MyString[20];.
While writing C++ code, you encounter some C functions which require C string as parameter.
Like below:
void IAmACFunction(int abc, float bcd, const char * cstring);
Now there is a problem. You are working with C++ and you are using std::string string variables. But this C function is asking for a C string. How do you convert your std::string to a standard C string?
Like this:
std::string MyString;
// ...
MyString = "Hello world!";
// ...
IAmACFunction(5, 2.45f, MyString.c_str());
This is what c_str() is for.
Note that, for std::wstring strings, c_str() returns a const w_char *.
Most old C++ and C functions, when dealing with strings, use const char*.
With STL and std::string, string.c_str() is introduced to be able to convert from std::string to const char*.
That means that if you promise not to change the buffer, you'll be able to use read-only string contents. PROMISE = const char*
In C/C++ programming there are two types of strings: the C strings and the standard strings. With the <string> header, we can use the standard strings. On the other hand, the C strings are just an array of normal chars. So, in order to convert a standard string to a C string, we use the c_str() function.
For example
// A string to a C-style string conversion //
const char *cstr1 = str1.c_str();
cout<<"Operation: *cstr1 = str1.c_str()"<<endl;
cout<<"The C-style string c_str1 is: "<<cstr1<<endl;
cout<<"\nOperation: strlen(cstr1)"<<endl;
cout<<"The length of C-style string str1 = "<<strlen(cstr1)<<endl;
And the output will be,
Operation: *cstr1 = str1.c_str()
The C-style string c_str1 is: Testing the c_str
Operation: strlen(cstr1)
The length of C-style string str1 = 17
c_str() converts a C++ string into a C-style string which is essentially a null terminated array of bytes. You use it when you want to pass a C++ string into a function that expects a C-style string (e.g., a lot of the Win32 API, POSIX style functions, etc.).
It's used to make std::string interoperable with C code that requires a null terminated char*.
You will use this when you encode/decode some string object you transfer between two programs.
Let’s say you use Base64 to encode some array in Python, and then you want to decode that into C++. Once you have the string you decode from Base64-decoded in C++. In order to get it back to an array of float, all you need to do here is:
float arr[1024];
memcpy(arr, ur_string.c_str(), sizeof(float) * 1024);
This is pretty common use, I suppose.
const char* c_str() const;
It returns a pointer to an array that contains a null-terminated sequence of characters (i.e., a C string), representing the current value of the string object.
This array includes the same sequence of characters that make up the value of the string object plus an additional terminating null - character ('\0') at the end.
std::string str = "hello";
std::cout << str; // hello
printf("%s", str); // ,²/☺
printf("%s", str.c_str()); // hello

Convert std::string to char * alternative

I have done a search in google and been told this is impossible as I can only get a static char * from a string, so I am looking for an alternative.
Here is the situation:
I have a .txt file that contains a list of other .txt files and some numbers, this is done so the program can be added to without recompilation. I use an ifstream to read the filenames into a string.
The function that they are required for is expecting a char * not a string and apparently this conversion is impossible.
I have access to this function but it calls another function with the char * so I think im stuck using a char *.
Does anyone know of a work around or another way of doing this?
In C++, I’d always do the following if a non-const char* is needed:
std::vector<char> buffer(str.length() + 1, '\0');
std::copy(str.begin(), str.end(), buffer.begin());
char* cstr = &buffer[0];
The first line creates a modifiable copy of our string that is guaranteed to reside in a contiguous memory block. The second line gets a pointer to the beginning of this buffer. Notice that the vector is one element bigger than the string to accomodate a null termination.
You can get a const char* to the string using c_str:
std::string str = "foo bar" ;
const char *ptr = str.c_str() ;
If you need just a char* you have to make a copy, e.g. doing:
char *cpy = new char[str.size()+1] ;
strcpy(cpy, str.c_str());
As previous posters have mentioned if the called function does in fact modify the string then you will need to copy it. However for future reference if you are simply dealing with an old c-style function that takes a char* but doesn't actually modfiy the argument, you can const-cast the result of the c_str() call.
void oldFn(char *c) { // doesn't modify c }
std::string tStr("asdf");
oldFn(const_cast< char* >(tStr.c_str());
There is c_str(); if you need a C compatible version of a std::string. See http://www.cppreference.com/wiki/string/basic_string/c_str
It's not static though but const. If your other function requires char* (without const) you can either cast away the constness (WARNING! Make sure the function doesn't modify the string) or create a local copy as codebolt suggested. Don't forget to delete the copy afterwards!
Can't you just pass the string as such to your function that takes a char*:
func(&string[0]);

How to assign a string to char *pw in c++

How to assign a string to a char* (char pointer) in C++?
char *pw = some string
For constant initialization you can simply use
const char *pw = "mypassword";
if the string is stored in a variable, and you need to make a copy of the string then you can use strcpy() function
char *pw = new char(strlen(myvariable) + 1);
strcpy(pw, myvariable);
// use of pw
delete [] pw; // do not forget to free allocated memory
If you just want to assign a string literal to pw, you can do it like char *pw = "Hello world";.
If you have a C++ std::string object, the value of which you want to assign to pw, you can do it like char *pw = some_string.c_str(). However, the value that pw points to will only be valid for the life time of some_string.
If you mean a std::string, you can get a pointer to a C-style string from it, by calling c_str. But the pointer needs to be const.
const char *pw = astr.c_str();
If pw points to a buffer you've previously allocated, you might instead want to copy the contents of a string into that buffer:
astr.copy(pw, lengthOfBuffer);
If you're starting with a string literal, it's already a pointer:
const char *pw = "Hello, world".
Notice the const again - string literals should not be modified, as they are compiled into your program.
But you'll have a better time generally if you use std::string everywhere:
std::string astr("Hello, world");
By the way, you need to include the right header:
#include <string>
I think you may want to do this:
using namespace std;
string someString;
geline(cin,someString);
char *pw = strdup(someString.c_str());
But consider doing it another way. Check out http://tiswww.case.edu/php/chet/readline/rltop.html (GNU Readline library). I don't know details about it, just heard about it. Others may have more detailed or other tips for reading passwords from standard input.
If you only want to use it for a single call for something you do not need to copy the contents of someString, you may use someString.c_str() directly if it is required as const char *.
You have to use free on pw some time later,
String must be enclosed in double quotes like :
char *pStr = "stackoverflow";
It will store this string literal in the read only memory of the program.
And later on modification to it may cause UB.