C++ Int to String by using ostringstream or stringstream - c++

I've been using stringstream to convert Integer to String, but then I realized same operation can be done with ostringstream.
When I use .str() what is the difference between them? Also, is there more efficient way to convert integers to strings?
Sample code:
//using ostringstream
ostringstream s1;
int i=100;
s1<<i;
string str_i=s1.str();
cout<<str_i<<endl;
//using stringstream
stringstream s2;
int i2=100;
s2<<i2;
string str_i2=s2.str();
cout<<str_i2<<endl;

There is a third that you didn't mention, istringstream, which you can't use (well you could but it would be different, you can't << to an istringstream).
stringstream is both an ostringstream and an istringstream - you can << and >> both ways, in and out.
With ostringstream, you can only go in with <<, and you cannot go out with >>.
There isn't really a difference, you can use either way to convert strings to integers. If you want to do it the fastest way possible, I think boost::lexical_cast has that title, or you could use the itoa function which may be faster than stringstream, but you lose the advantages of C++ and the standard library if you use itoa (you have to use C-strings, etc).
Also, as Benjamin Lindley informed us, C++11 has the ultramagical std::to_string.

Related

What's the necessity of string in c++ while we already have char[]?

Many topics have discussed the difference between string and char[]. However, they are not clear to me to understand why we need to bring string in c++? Any insight is welcome, thanks!
char[] is C style. It is not object oriented, it forces you as the programmer to deal with implementation details (such as '\0' terminator) and rewrite standard code for handling strings every time over and over.
char[] is just an array of bytes, which can be used to store a string, but it is not a string in any meaningful way.
std::string is a class that properly represents a string and handles all string operations.
It lets you create objects and keep your code fully OOP (if that is what you want).
More importantly, it takes care of memory management for you.
Consider this simple piece of code:
// extract to string
#include <iostream>
#include <string>
main ()
{
std::string name;
std::cout << "Please, enter your name: ";
std::cin >> name;
std::cout << "Hello, " << name << "!\n";
return 0;
}
How would you write the same thing using char[]?
Assume you can not know in advance how long the name would be!
Same goes for string concatenation and other operations.
With real string represented as std::string you combine two strings with a simple += operator. One line.
If you are using char[] however, you need to do the following:
Calculate the size of the combined string + terminator character.
Allocate memory for the new combined string.
Use strncpy to copy first string to new array.
Use strncat to append second string to first string in new array.
Plus, you need to remember not to use the unsafe strcpy and strcat and to free the memory once you are done with the new string.
std::string saves you all that hassle and the many bugs you can introduce while writing it.
As noted by MSalters in a comment, strings can grow. This is, in my opinion, the strongest reason to have them in C++.
For example, the following code has a bug which may cause it to crash, or worse, to appear to work correctly:
char message[] = "Hello";
strcat(message, "World");
The same idea with std::string behaves correctly:
std::string message{"Hello"};
message += "World";
Additional benefits of std::string:
You can send it to functions by value, while char[] can only be sent by reference; this point looks rather insignificant, but it enables powerful code like std::vector<std::string> (a list of strings which you can add to)
std::string stores its length, so any operation which needs the length is more efficient
std::string works similarly to all other C++ containers (vector, etc) so if you are already familiar with containers, std::string is easy to use
std::string has overloaded comparison operators, so it's easy to use with std::map, std::sort, etc.
String class is no more than an amelioration of the char[] variable.
With strings you can achieve the same goals than the use of a char[] variable, but you won't have to matter about little tricks of char[] like pointers, segmentation faults...
This is a more convenient way to build strings, but you don't really see the "undergrounds" of the language, like how to implement concatenation or length functions...
Here is the documentation of the std::string class in C++ : C++ string documentation

scanf function for strings

The problem is simple, the code below does not work. it says Process finished with exit code -1073740940 (0xC0000374). Removing ampersand does not change anything.
int main(){
string x;
scanf("%s",&x);
cout << x;
}
scanf() with the %s format specifier reads bytes into a preallocated character array (char[]), to which you pass a pointer.
Your s is not a character array. It is a std::string, a complex object.
A std::string* is not in any way the same as a char*. Your code overwrites the memory of parts of a complex object in unpredictable ways, so you end up with a crash.
Your compiler should have warned about this, since it knows that a char* is not a std::string*, and because compilers are clever and can detect mistakes like this despite the type-unsafe nature of C library functions.
Even if this were valid via some magic compatibility layer, the string is empty.
Use I/O streams instead.
You cannot pass complex objects through the ... operator of printf/scanf. Many compilers print a warning for that.
scanf requires a pointer of type char* pointing to sufficient storage for an argument of %s. std::string is something completely different.
In C++ the iostream operators are intended for text input and output.
cin >> x;
will do the job.
You should not use scanf in C++. There are many pitfalls, you found one of them.
Another pitfall: %s at scanf is almost always undefined behavior unless you you really ensure that the source stream can only contain strings of limited size. In this case a buffer of char buffer[size]; is the right target.
In any other case you should at least restrict the size of the string to scan. E.g. use %20s and of course a matching char buffer, char buffer[21];in this case. Note the size +1.
You should use cin. But if you want to use scanf() for whatever reason and still manipulate your strings with std::string, then you can read the C-string and use it to initialize your C++ string.
#include <iostream>
#include <cstdio>
#include <string>
using std::cout;
using std::string;
int main()
{
char c_str[80];
scanf("%s", c_str);
string str(c_str);
cout << str << "\n";
}
If you want to use strings, use cin (or getline).
string s;
cin>>s; //s is now read
If you want to use scanf, you want to have a char array (and don't use &):
char text[30];
scanf("%s", text); //text is now read
You can use char[] instead of string
include <iostream>
using namespace std;
int main()
{
char tmp[101];
scanf("%100s", tmp);
cout << tmp;
}

Using a character array as a string stream buffer

I'm looking for a clean STL way to use an existing C buffer (char* and size_t) as a string stream. I would prefer to use STL classes as a basis because it has built-in safeguards and error handling.
note: I cannot use additional libraries (otherwise I would use QTextStream)
You can try with std::stringbuf::pubsetbuf. It calls setbuf, but it's implementation defined whether that will have any effect. If it does, it'll replace the underlying string buffer with the char array, without copying all the contents like it normaly does. Worth a try, IMO.
Test it with this code:
std::istringstream strm;
char arr[] = "1234567890";
strm.rdbuf()->pubsetbuf(arr, sizeof(arr));
int i;
strm >> i;
std::cout << i;
Live demo.

Fastest way to input huge strings?

I have to read huge lines of strings from stdin so time is a critical issue. Strings are on consecutive lines and have no spaces so I can simply use while(cin>>str) { //code } but this is extremely slow. I have heard that scanf is much more faster than cin but if I use scanf("%s,str) I think that str is treated as char* and not a C++ string so I can't use the STL. I could take input as char* and copy all the chars into a C++ string but IMO that will also be slow.
Is there a way to get input using scanf or something but still get a C++ string as a result?
If you know the average or maximum size of the text, you create std::string with a pre-allocated size. One area occupying a lot of time is the memory (re) allocation by std::string.
cin >> str is the closest thing you'll find in STL to scanf("%s, str"). The only reason scanf would be faster than cin is because it would be giving you a char* instead of a string, and while you can create a new string from the char* by just passing them in to the string() constructor, that would be almost the same thing as using cin >> str.
You can use getline:
for (std::string line; getline(std::cin, line); ) {
do_something_with(line);
}
I don't know if it is any faster than cin >> line, but it might be, since it doesn't need to deal with whitespace other than newlines. But I don't believe this is as significant as the overhead of sentry construction.

When should I use string instead of stringstream?

When should I use stringstream instead of string::append()?
Supposing I'm going to catenate just strings.
stringstream ss;
ss << str1 << "str2" << ...
Write(ss.str());
Or:
string str;
str.reserve(10000);
str.append(str1);
str.append("str2");
...
Write(str);
Which of them is faster?
I don't know which one will be faster, but if I had to guess I'd say your second example is, especially since you've called the reserve member function to allocate a large space for expansion.
If you're only concatenating strings use string::append (or string::operator+=).
If you're going to convert numbers to their string representation, as well as format them during conversion, and then append the conversion results together, use stringstreams. I mention the formatting part explicitly because if you do not require formatting C++11 offers std::to_string which can be used to convert numeric types to strings.
string.append is much faster. Especially when you reserve.
If you are concatenating only strings, I would use string.append. I would only use stringstream when I need to automatically convert non-strings to strings for example:
const int x(42);
stringstream ss;
ss << "My favorite number is: " << x << std::endl;
Here stringstream automatically converts x to a string and appends it. I do not need to call atoi. Stringstream will convert all the basic types automatically for you. It is great for that purpose.
Also if you are only going to be directing data into the stringstream to convert it to a string later. You can use ostringstream which is for output.
I hope that helps.