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;
Related
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(); }
In Lua (apologise, I like working with it the best), the conversion between int and string is done automatically, so
"hi"..2
would result as
"hi2"
In C++ (cause I can't seem to get the default C++11 stoi() and to_string() methods to work) I defined these for myself:
int stoi(string str) {
char* ptr;
strtol(str.c_str(), &ptr, 10);
}
string to_string(int i) {
char* buf;
sprintf(buf, "%d", i);
return buf;
}
which are basically how the default ones are defined anyways.
Then I did this:
string operator+ (string& stuff, int why) {
stuff.append(to_string(why));
}
I tried it on the following code:
void print(string str) {
cout << str << endl;
}
int main() {
cout << stoi("1") + 2 << endl;
print("die" + 1);
return 0;
}
And it outputs
3
ie
Why is this so, and how can I fix it?
EDIT:
Here's what the code looks like now:
using namespace std;
string to_string(int i) {
char* buf;
sprintf(buf, "%d", i);
return buf;
}
string operator+ (string stuff, int why) {
stuff.append(to_string(why));
return stuff;
}
int main() {
cout << string("die") + 2 << endl;
return 0;
}
And it just keeps giving me stackdumps.
Replace print("die" + 1); with cout << std::string("die") + 1;
print() doesn't know what to do with strings. Use std::cout. "die" is a char*, +1 will increment the pointer.
std::string to_string(int i) {
char buf[(sizeof(int)*CHAR_BIT+2)/3+3];
sprintf(buf, "%d", i);
return buf;
}
You need to make an actual buffer to print to. The math is a quick over-estimate of big the largest decimal int is in characters; 3 bits can fit in 1 decimal character, plus null, plus negation, plus rounding, plus 1 for good measure. Hopefully I did not err: do some testing.
Also use snprintf instead of sprintf while you are at it: buffer overflows are not to be toyed with.
The next problem is that "hello" is not a std::string, It is a char const[6] -- an array of 6 char. It can be converted tomstd::string, but +1 will instead convert it to a pointer to the first character, then +1 it to the 2nd character.
Cast it to std::string before.
Finally, it is ambiguous in the standard (really) of pverloading an operator on std::string + int is legal. It is definitely poor practice, as you cannot do it in std legally, and you should overload operators in the type's namespace (so ADL works): these two conflict. On top of that, if std in the future adds such a + your code starts behaving strangely. On top of that, operators are part of a class's interface, and modifying the interface of a class you do not 'own' is rude and a bad habit.
Write your own string class that owns a std::string rather. Or a string view.
Finally, consider telling your compiler to use c++11, you probably just need to pass a flag to it like -std=c++11.
std::string s1("h1");
std::string s2("2");
s1 += s2;
If you are using C++11 compatible compiler you can convert int to string like this:
int i = 2;
std::string s = std::to_string(i);
If you are using Boost library:
#include <boost/lexical_cast.hpp>
int i = 2;
std::string s = boost::lexical_cast<std::string>(i);
Please do not use raw char pointers in C++ for strings.
overloading the operator+ on other than your own types it at best dangerous.
Just use std::to_string in conjunction with operator+ or +=, e.g.
std::string x = "hi";
x += std::to_string(2);
C++14 introduces a user-defined literal that takes a string literal (conversions are applied to make this a pointer) and returns a std::string. In C++11, you can just write your own (this is taken from libstdc++):
inline std::string
operator""_s(const char* str, size_t len)
{
return std::string{str, len};
}
(Note: UDLs without a preceding underscore are reserved names)
And you can use it like this:
// Assumes operator+ is overloaded
print("die"_s + 1);
Demo
"die" is not a std::string. It's a string literal.
Thus when you add 1 to the string literal, it decays to a const char* and the + 1 simply increments that pointer — to next char, 'i'.
Then you call print with the incremented pointer, which causes a std::string to be constructed using that pointer. Since it pointed to the 'i' character, to constructed string is initialized to "ie".
You must first make a std::string out of your string literal to make it call your operator+:
std::cout << std::string("die") + 1;
And then make a few fixes to your operator+:
string operator+ (string stuff, int why) {
return stuff.append(to_string(why));
}
Now it works.
In the below code, i am expecting output to be abc#def. But i am getting output as abcdef. It seems strtok is modifying the vector even though i am not directly passing vector to the strtok function. May i know how it is happening inside
std::vector<std::pair<const std::string, int>> x;
std::vector<std::string> z;
int main()
{
char* pch;
x.push_back(std::make_pair("abc#def", 1));
std::string m = x[0].first;
pch = strtok ((char*)(m.c_str()),"#");
while (pch != NULL)
{
z.push_back(pch);
pch =strtok (NULL, "#");
}
cout<<x[0].first<<endl;
return 0;
}
Copied instances of std::string may use the same backing buffer. That is x[0] and m may actually use the same backing buffer.
This is why the c_str() member returns const char * - you are not allowed to modify it.
You are casting away the const by using the C-style cast (char *).
In general, better use C++ casts: static_cast<>/reinterpret_cast<>/dynamic_cast<> and const_cast<> if you really need to strip the const. The latter is only intended to interface old C-code without const qualifiers. You shall not require to use it within normal C++ code.
Instead using of strtok use find_first_of & find_first_not_of methods of string
like this:
using namespace std;
int main () {
string s="abc#def";
string temp = s,res;
while(temp.size()){
size_t st,en;
st = temp.find_first_not_of("#");
en = temp.find_first_of("#",st);
res= temp.substr(st,en);
cout<<res.c_str()<<endl;
temp=(en == string::npos) ? "" : temp.substr(en);
}
return 0;
}
In your implementation, c_str() must be returning a reference to the internal char buffer of the string, without making any copy. From the manpage of glibc strtok:
BUGS
Be cautious when using these functions. If you do use them, note that:
These functions modify their first argument.
so, yes, strtok applied to the pointer returned from c_str() will modify the string buffer.
You should be using std::getline instead of strtok to split string at #:
std::vector<std::pair<const std::string, int>> x;
int main() {
x.push_back(std::make_pair("abc#def", 1));
std::string m = x[0].first;
std::string token;
while(std::getline(m, token, '#')) {
std::cout << token << std::endl;
}
cout<< x[0].first <<endl;
return 0;
}
or, if you really need to use strtok, at least duplicate the buffer returned by c_str() with strdup (and remember to free() it).
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.
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.