I want to make string which is influenced by variables changing (c++) - c++

I'm using stringstream in put variables in string like
int c;
stringstream ss;
string st;
ss << "some texts" << c;
st=ss.str();
cout << st;
but when i change the c and call back ss.str() again, ss.str() is saving
ex-int c, not new one.
Is there any functions or way to string is influenced by changing variable here?

Stringstream doesn't bind to the variable, you have 2 options
1) Create your own class that binds to the int (saves a reference or something)
2) clear the stringstream like
ss.str(""); // clear stream
and then write to it again
ss << "some texts" << c; // set the stream again with modified c

Related

Stringstream returning blank value

Why does this program print out blank?
string str;
stringstream ss(str);
ss << "A string";
cout << str; // just blank
stringstream is not going to modify the argument you pass to its constructor.
Instead, you can get the current buffer from the stringstream by calling its str member function:
cout << ss.str();
Next time, consider reading the documentation.

What exactly does stringstream do?

I am trying to learn C++ since yesterday and I am using this document: http://www.cplusplus.com/files/tutorial.pdf (page 32). I found a code in the document and I ran it. I tried inputting Rs 5.5 for price and an integer for quantity and the output was 0.
I tried inputting 5.5 and 6 and the output was correct.
// stringstreams
#include <iostream>
#include <string>
#include <sstream>
using namespace std;
int main ()
{
string mystr;
float price = 0;
int quantity = 0;
cout << "Enter price: ";
getline (cin,mystr);
stringstream(mystr) >> price;
cout << "Enter quantity: ";
getline (cin,mystr);
stringstream(mystr) >> quantity;
cout << "Total price: " << price*quantity << endl;
return 0;
}
What exactly does the mystring command do? Quoting from the document:
"In this example, we acquire numeric values from the standard input
indirectly. Instead of extracting numeric values directly from the
standard input, we get lines from the standard input (cin) into a
string object (mystr), and then we extract the integer values from
this string into a variable of type int (quantity)."
My impression was that the function will take an integral part of a string and use that as input.
Sometimes it is very convenient to use stringstream to convert between strings and other numerical types. The usage of stringstream is similar to the usage of iostream, so it is not a burden to learn.
Stringstreams can be used to both read strings and write data into strings. It mainly functions with a string buffer, but without a real I/O channel.
The basic member functions of stringstream class are
str(), which returns the contents of its buffer in string type.
str(string), which set the contents of the buffer to the string argument.
Here is an example of how to use string streams.
ostringstream os;
os << "dec: " << 15 << " hex: " << std::hex << 15 << endl;
cout << os.str() << endl;
The result is dec: 15 hex: f.
istringstream is of more or less the same usage.
To summarize, stringstream is a convenient way to manipulate strings like an independent I/O device.
FYI, the inheritance relationships between the classes are:
From C++ Primer:
The istringstream type reads a string, ostringstream writes a string, and stringstream reads and writes the string.
I come across some cases where it is both convenient and concise to use stringstream.
case 1
It is from one of the solutions for this leetcode problem. It demonstrates a very suitable case where the use of stringstream is efficient and concise.
Suppose a and b are complex numbers expressed in string format, we want to get the result of multiplication of a and b also in string format. The code is as follows:
string a = "1+2i", b = "1+3i";
istringstream sa(a), sb(b);
ostringstream out;
int ra, ia, rb, ib;
char buff;
// only read integer values to get the real and imaginary part of
// of the original complex number
sa >> ra >> buff >> ia >> buff;
sb >> rb >> buff >> ib >> buff;
out << ra*rb-ia*ib << '+' << ra*ib+ia*rb << 'i';
// final result in string format
string result = out.str()
case 2
It is also from a leetcode problem that requires you to simplify the given path string, one of the solutions using stringstream is the most elegant that I have seen:
string simplifyPath(string path) {
string res, tmp;
vector<string> stk;
stringstream ss(path);
while(getline(ss,tmp,'/')) {
if (tmp == "" or tmp == ".") continue;
if (tmp == ".." and !stk.empty()) stk.pop_back();
else if (tmp != "..") stk.push_back(tmp);
}
for(auto str : stk) res += "/"+str;
return res.empty() ? "/" : res;
}
Without the use of stringstream, it would be difficult to write such concise code.
To answer the question. stringstream basically allows you to treat a string object like a stream, and use all stream functions and operators on it.
I saw it used mainly for the formatted output/input goodness.
One good example would be c++ implementation of converting number to stream object.
Possible example:
template <class T>
string num2str(const T& num, unsigned int prec = 12) {
string ret;
stringstream ss;
ios_base::fmtflags ff = ss.flags();
ff |= ios_base::floatfield;
ff |= ios_base::fixed;
ss.flags(ff);
ss.precision(prec);
ss << num;
ret = ss.str();
return ret;
};
Maybe it's a bit complicated but it is quite complex. You create stringstream object ss, modify its flags, put a number into it with operator<<, and extract it via str(). I guess that operator>> could be used.
Also in this example the string buffer is hidden and not used explicitly. But it would be too long of a post to write about every possible aspect and use-case.
Note: I probably stole it from someone on SO and refined, but I don't have original author noted.
You entered an alphanumeric and int, blank delimited in mystr.
You then tried to convert the first token (blank delimited) into an int.
The first token was RS which failed to convert to int, leaving a zero for myprice, and we all know what zero times anything yields.
When you only entered int values the second time, everything worked as you expected.
It was the spurious RS that caused your code to fail.

How to Convert Hex String to Uint8

I would like to know why I am getting the result of 0 when converting a hex string (0x1) to a uint8.
I tried to use boost::lexical_cast but I get a bad_lexical_cast exception. Therefore, I decided to use a stringstream instead but I am getting the incorrect value.
...
uint8_t temp;
std::string address_extension = "0x1";
std::cout << "Before: " << address_extension << std::endl;
StringToNumeric(address_extension, temp);
std::cout << "After: " << temp << std::endl;
...
template <typename T>
void StringToNumeric(const std::string& source, T& target)
{
//Check if source is hex
if(IsHexNotation(source))
{
std::stringstream ss;
//Put value in the stream
ss << std::hex << source;
//Stream the hex value into a target type
ss >> target;
}
}
You can be assured that IsHexNotation() works correctly and does not change the source as it is declared:
bool IsHexNotation(const std::string& source)
What is the correct way to convert a hex string to a uint8 (given that the hex string WILL fit into the datatype)?
Using code like this works for me:
std::stringstream ss;
int target(0);
ss << std::hex << source;
if (ss >> target) {
std::cout << "value=" << target << '\n';
}
else {
std::cout << "failed to read value\n";
}
However, I remember that there was a discussion on where the read position of a string stream should be after a write. Since it mostly follows the model of file streams, you'd need to seek to desired position, even if it is the same position. Some implementations used a common position and others used separate read and write positions. You can try using
ss.seekg(0, std::ios_base::beg);
to make sure that the read position is at the start of the stream. Alternatively, and in my opinion preferable, is to initialize an std::istringstream and read from that directly:
std::istringstream in(source);
if (in >> std::hex >> target) { ... }
Note, that you always want to check if the extraction was successful: this way you get a hint that something actually went wrong and the value 0 may be just some initial value of the variable.

String concatenation in C++ problem

everybody I have problem with string concatenation in C++, here is my code
map<double, string> fracs;
for(int d=1; d<=N; d++)
for(int n=0; n<=d; n++)
if(gcd(n, d)==1){
string s = n+"/"+d;// this does not work in C++ but works in Java
fracs.insert(make_pair((double)(n/d), s));
}
How can I fix my code?
Try like this.
stringstream os;
os << n << "/" << d;
string s =os.str();
In C++ you have to convert an int to a string before you can concatenate it with another string using the + operator.
See Easiest way to convert int to string in C++.
Use streams, in your case, a stringstream:
#include <sstream>
...
std::stringstream ss;
ss << n << '/' << d;
Later, when done with your work, you can store it as an ordinary string:
const std::string s = ss.str();
Important (side-) note: Never do
const char *s = ss.str().c_str();
stringstream::str() produces a temporary std::string, and according to the standard, temporaries live until the end of the expression. Then, std::string::c_str() gives you a pointer to a null-terminated string, but according to The Holy Law, that C-style-string becomes invalid once the std::string (from which you receved it) changes.
It might work this time, and next time, and even on QA, but explodes right in the face of your most valuable customer.
The std::string must survive until the battle is over:
const std::string s = ss.str(); // must exist as long as sz is being used
const char *sz = s.c_str();
n and d are integers. Here is how you can convert integer to string:
std::string s;
std::stringstream out;
out << n << "/" << d;
s = out.str();
You could use a stringstream.
stringstream s;
s << n << "/" << d;
fracs.insert(make_pair((double)n/d, s.str()));
No one has suggested it yet but you can also take a look at boost::lexical_cast<>.
While this method is sometimes criticized because of performance issues, it might be ok in your situation, and it surely makes the code more readable.
Unlike in Java, in C++ there is no operator+ that explicitly converts a number to a string. What is usually done in C++ in cases like this is...
#include <sstream>
stringstream ss;
ss << n << '/' << d; // Just like you'd do with cout
string s = ss.str(); // Convert the stringstream to a string
I think sprintf(), which is a function used to send formatted data to strings, would be a much clearer way to do it. Just the way you would use printf, but with the c-style string type char* as a first(additional) argument:
char* temp;
sprint(temp, "%d/%d", n, d);
std::string g(temp);
You could check it out at http://www.cplusplus.com/reference/cstdio/sprintf/

Writing stringstream contents into ofstream

I'm currently using std::ofstream as follows:
std::ofstream outFile;
outFile.open(output_file);
Then I attempt to pass a std::stringstream object to outFile as follows:
GetHolesResults(..., std::ofstream &outFile){
float x = 1234;
std::stringstream ss;
ss << x << std::endl;
outFile << ss;
}
Now my outFile contains nothing but garbage: "0012E708" repeated all over.
In GetHolesResults I can write
outFile << "Foo" << std:endl;
and it will output correctly in outFile.
Any suggestion on what I'm doing wrong?
You can do this, which doesn't need to create the string. It makes the output stream read out the contents of the stream on the right side (usable with any streams).
outFile << ss.rdbuf();
If you are using std::ostringstream and wondering why nothing get written with ss.rdbuf() then use .str() function.
outFile << oStream.str();
When passing a stringstream rdbuf to a stream newlines are not translated. The input text can contain \n so find replace won't work. The old code wrote to an fstream and switching it to a stringstream losses the endl translation.
I'd rather write ss.str(); instead of ss.rdbuf(); (and use a stringstream).
If you use ss.rdbuf() the format-flags of outFile will be reset rendering your code non-reusable.
I.e., the caller of GetHolesResults(..., std::ofstream &outFile) might want to write something like this to display the result in a table:
outFile << std::setw(12) << GetHolesResults ...
...and wonder why the width is ignored.