Cannot convert std::stringstream<char> to const char* - c++

I tried to run command with help of system() function, forwarding argument as in code below:
std::stringstream volume_control;
int volume_value = 5;
volume_control << "/usr/bin/amixer cset numid=1 " << volume_value << std::endl;
system(volume_control.str());
It doesn't work, because of unsuccessful conversion of std::stringstream to const char*.
I know that in std::string case I have method std::c_string() and If I'm right it returns exactly what I need const char* type, but in this case of stringstream that method does not exist. So what to do?

volume_control.str() returns a std::string type. You need to call std::string::c_str() or std::string::data() method on it.
A google search would have easily given you the answer.
system(volume_control.str().c_str());

You should use c_str method on string returned from str method.
system(volume_control.str().c_str());

You can refer to this link
stringstream, string, and char* conversion confusion
{ const std::string& tmp = stringstream.str(); const char* cstr = tmp.c_str(); }

Related

C++ stringstream concatenate query

The code is supposed to concatenate argv[1] with .txt , and with _r.txt .
std::stringstream sstm;
std::stringstream sstm_r;
sstm<<argv[1]<<".txt";
sstm_r<<argv[1]<<"_r.txt";
const char* result = sstm.str().c_str();
const char* result_r = sstm_r.str().c_str();
fs.open(result);
fs_r.open(result_r);
cout<<result<<endl;
cout<<result_r<<endl;
But what it does is ,
when i enter "abc" as argv[1] , it gives me , result as "abc_r.tx0" and result_r also same "abc_r.tx0" .What is the correct way to do this and why is this wrong .
The std::string instances to which the pointers returned by c_str() are associated will be destroyed leaving result and result_r as dangling pointers, resulting in undefined behaviour. You need to save the std::string instances if you want to use c_str():
const std::string result(sstm.str());
fs.open(result.c_str()); /* If this is an fstream from C++11 you
can pass a 'std::string' instead of a
'const char*'. */
Work with the strings like this:
{
const std::string& tmp = stringstream.str();
const char* cstr = tmp.c_str();
}
This is taken from another exchange here.

C strings vs const char* is confusing me... help please

I'm a C/C++ beginner trying to build what seems like a pretty simple program: it loads a file into a c-string (const char*). However, although the program is incredibly simple, it's not working in a way I understand. Take a look:
#include <iostream>
#include <fstream>
std::string loadStringFromFile(const char* file)
{
std::ifstream shader_file(file, std::ifstream::in);
std::string str((std::istreambuf_iterator<char>(shader_file)), std::istreambuf_iterator<char>());
return str;
}
const char* loadCStringFromFile(const char* file)
{
std::ifstream shader_file(file, std::ifstream::in);
std::string str((std::istreambuf_iterator<char>(shader_file)), std::istreambuf_iterator<char>());
return str.c_str();
}
int main()
{
std::string hello = loadStringFromFile("hello.txt");
std::cout << "hello: " << hello.c_str() << std::endl;
const char* hello2 = loadCStringFromFile("hello.txt");
std::cout << "hello2: " << hello2 << std::endl;
hello2 = hello.c_str();
std::cout << "hello2 = hello.c_str(), hello2: " << hello2 << std::endl;
return 0;
}
The output looks like this:
hello: Heeeeyyyyyy
hello2: 青!
hello2 = hello, hello2: Heeeeyyyyyy
The initial hello2 value changes every time, always some random kanji (I'm using a Japanese computer, so I'm guessing that's why it's kanji).
In my naive view, it seems like the two values should print identically. One function returns a c++ string, which I then convert to a c-string, and the other loads the string, converts the c-string from that and returns it. I made sure that the string was loading properly in loadCStringFromFile by couting the value before I returned it, and indeed it was what I had thought, e.g.:
/*(inside loadCStringFromFile)*/
const char* result = str.c_str();
std::cout << result << std::endl;//prints out "Heeeyyyyyy" as expected
return result;
So why should the value change? Thanks for the help...
Your problem is that str in loadCStringFromFile is a local variable, and is destructed when the function returns. At that point the return value from c_str() is invalid.
More detail here
Your first function, loadStringFromFile, is a more C++-like way of doing it, and illustrates the benefit of having a class manage memory for you. If you use char* then you have to take much more care where memory is allocated and freed.
the function
std::string loadStringFromFile(const char* file)
returns a string copy of the string created inside the function which is copied before the string goes out of scope i.e. the function ends, that is why it works.
const char* loadCStringFromFile(const char* file)
on the other hand returns a pointer to the local string which goes out of scope when the function returns and is destroyed so the returned address, the const char*, points to somewhere undefined.
in order for the second way to work you either need to create the string before calling the function :
const char* loadCStringFromFile(const char* file, string& str); // return str.c_str()
..
string str;
const char* result = loadCStringFromFile(file,str);
or you create a string on the heap in the function and pass the address back, but that gets a bit messy since the caller would need to delete the string to avoid memleak.
You should duplicate output of str.c_str():
return strdup(str.c_str);
function strdup can be found in cstring header.

Pass a string in C++

Quick probably obvious question.
If I have:
void print(string input)
{
cout << input << endl;
}
How do I call it like so:
print("Yo!");
It complains that I'm passing in char *, instead of std::string. Is there a way to typecast it, in the call? Instead of:
string send = "Yo!";
print(send);
You can write your function to take a const std::string&:
void print(const std::string& input)
{
cout << input << endl;
}
or a const char*:
void print(const char* input)
{
cout << input << endl;
}
Both ways allow you to call it like this:
print("Hello World!\n"); // A temporary is made
std::string someString = //...
print(someString); // No temporary is made
The second version does require c_str() to be called for std::strings:
print("Hello World!\n"); // No temporary is made
std::string someString = //...
print(someString.c_str()); // No temporary is made
You should be able to call print("yo!") since there is a constructor for std::string which takes a const char*. These single argument constructors define implicit conversions from their aguments to their class type (unless the constructor is declared explicit which is not the case for std::string). Have you actually tried to compile this code?
void print(std::string input)
{
cout << input << endl;
}
int main()
{
print("yo");
}
It compiles fine for me in GCC. However, if you declared print like this void print(std::string& input) then it would fail to compile since you can't bind a non-const reference to a temporary (the string would be a temporary constructed from "yo")
Well, std::string is a class, const char * is a pointer. Those are two different things. It's easy to get from string to a pointer (since it typically contains one that it can just return), but for the other way, you need to create an object of type std::string.
My recommendation: Functions that take constant strings and don't modify them should always take const char * as an argument. That way, they will always work - with string literals as well as with std::string (via an implicit c_str()).
print(string ("Yo!"));
You need to make a (temporary) std::string object out of it.
For easy stuff like printing, you can define a sort of function in your preprocessors like:
#define print(x) cout << x << endl
The obvious way would be to call the function like this
print(string("Yo!"));
Make it so that your function accepts a const std::string& instead of by-value. Not only does this avoid the copy and is therefore always preferable when accepting strings into functions, but it also enables the compiler to construct a temporary std::string from the char[] that you're giving it. :)
Just cast it as a const char *.
print((const char *)"Yo!") will work fine.

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

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.

string to integer

I can't do this in C++
string temp = "123";
int t = atoi(temp);
why????
That is because atoi is expecting a raw const char* pointer. Since there is no implicit conversion from std::string to const char* you get a compiler error. Use c_str() method of std::string to get a c-style const char* for a std::string object. BTW, in C++ you can use streams to do this conversion instead of using these C-style APIs.
atoi(temp.c_str())
See these questions:
C atoi() string to int: Points out that atoi() is deprecated.
Why doesn't C++ reimplement C standard functions with C++ elements style?: Gives alternate ways to do what you've listed above.
Well, you passed a std::string (presumably) to atoi, which takes a const char*. Try:
atoi(temp.c_str());
which was previously mentioned. Instead, you could use boost's lexical_cast:
std::string temp = "123";
try {
int foo = boost::lexical_cast<int>(temp);
} catch (boost::bad_lexical_cast e) {
//handle error here
}
You could wrap the try/catch into a template function that handles the exceptions in the event that you do not already have exception handling in place.
std::string is not the same as a character pointer (like in C).
int i = 12345;
std::string s;
std::stringstream sstream;
sstream << i;
sstream >> s;