error with std::ostringsteam and std::string - c++

Hi i want to save many different csv files from a function with a naming convention based on a different double value. I do this with a for loop and pass a string value to save each .csv file differently. Below is an example of what I'm trying to do the desired result would be
1.1_file.csv
1.2_file.csv
but instead i get
1.1_file.csv
1.11.2_file.csv
Here is a working sample code, what can i do to fix this
#include <sstream>
#include <iomanip>
#include <cmath>
#include <iostream>
#include <vector>
int main(){
std::string file = "_file.csv";
std::string s;
std::ostringstream os;
double x;
for(int i = 0; i < 10; i++){
x = 0.1 + 0.1 *i;
os << std::fixed << std::setprecision(1);
os << x;
s = os.str();
std::cout<<s+file<<std::endl;
s.clear();
}
return 0;
}

The ostringstream doesn't reset on each iteration of the loop, so you are just adding x to it every iteration; put it inside the scope of the for to make os be a different clean object on each iteration, or reset the contents with os.str("").
Also, the variable s is unnecessary; you can just do
std::cout << os.str() + file << std::endl;
And you don't need s and you eliminate the overhead of making a copy of the string.

Your ostringstream is getting appended for each iteration of the loop. You should clear it and reuse it as shown below (courtesy: How to reuse an ostringstream? on how to reuse an ostringstream)
#include <sstream>
#include <iomanip>
#include <cmath>
#include <iostream>
#include <vector>
int main() {
std::string file = "_file.csv";
std::string s;
double x;
std::ostringstream os;
for (int i = 0; i < 10; i++) {
x = 0.1 + 0.1 * i;
os << std::fixed << std::setprecision(1);
os << x;
s = os.str();
std::cout << s + file << std::endl;
os.clear();
os.str("");
}
return 0;
}

Related

std::stof precision problems

I've got a .txt file with multiple x y and z float numbers and I'm getting line by line with std::getline(file, line).
My problem is: while I'm getting the values correctly for x, y and z in strings, their decimal places are being reduced and that's not what I want.
I want to know how to store the full value. From what I saw I can use std::setprecision() to correct this while printing, but I want to correct the stored values so I can use them.
What can I do? Are the numbers stored properly but not shown properly by my std::cout? Here's the code:
#include <iostream>
#include <fstream>
#include <vector>
#include <string>
#include <regex>
int main()
{
std::string line;
std::ifstream input("input.txt");
std::vector<float> x;
std::vector<float> y;
std::vector<float> z;
std::regex reg("[,]+");
int line_count = 0;
if (input.is_open()) {
while (std::getline(input, line)) {
if (line_count > 0)
{
std::sregex_token_iterator iter(line.begin(), line.end(), reg, -1);
std::sregex_token_iterator end;
std::vector<std::string> tokens(iter, end);
std::cout << tokens[0] << std::endl;
x.push_back(std::stof(tokens[0]));
std::cout << x[line_count - 1] << std::endl;
y.push_back(std::stof(tokens[1]));
z.push_back(std::stof(tokens[2]));
}
line_count++;
}
}
/*for (size_t i = 0; i < x.size(); i++)
{
std::cout << x[i] << " " << y[i] << " " << z[i] << std::endl;
}*/
}
The .txt file is as follows:
x,y,z
-0.015869140625,0.896728515625,-0.103515625
-0.00634765625,0.8935546875,-0.147216796875
-0.00634765625,0.8935546875,-0.147216796875
-0.02197265625,0.9326171875,-0.10400390625
-0.02197265625,0.9326171875,-0.10400390625
-0.078369140625,0.944580078125,-0.126220703125
-0.078369140625,0.944580078125,-0.126220703125
-0.047119140625,0.979248046875,-0.114990234375
-0.047119140625,0.979248046875,-0.114990234375
0.022216796875,1.0068359375,-0.096435546875
-0.009033203125,1.02685546875,-0.078369140625
-0.009033203125,1.02685546875,-0.078369140625
-0.052490234375,1.033935546875,-0.114501953125
Double and float do not have that precision.
You can use The GNU Multiple Precision Arithmetic Library class mpf_class.

Build incremental std::string

I try to build an std::string in the form of "start:Pdc1;Pdc2;Pdc3;"
With following code I can build the repeated "Pdc" and the incremental string "123" but I'm unable to combine the two strings.
#include <string>
#include <algorithm>
#include <iostream>
#include <sstream>
#include <iterator>
#include <numeric>
int main()
{
std::ostringstream ss;
std::string hdr("start:");
std::fill_n(std::ostream_iterator<std::string>(ss), 3, "Pdc;");
hdr.append(ss.str());
std::string v("abc");
std::iota(v.begin(), v.end(), '1');
std::cout << hdr << std::endl;
std::cout << v << std::endl;
std::cout << "Expected output: start:Pdc1;Pdc2;Pdc3;" << std::endl;
return 0;
}
How can I build this string? Preferable without a while or for loop.
The expected output is: start:Pdc1;Pdc2;Pdc3;
std::strings can be concatenated via their operator+ (or +=) and integers can be converted via std::to_string:
std::string res("start:");
for (int i=0;i<3;++i){
res += "Pdc" + std::to_string(i+1) + ";";
}
std::cout << res << "\n";
If you like you can use an algorithm instead of the handwritten loop, but it will still be a loop (your code has 2 loops, but only 1 is needed).
Code to generate your expected string, though with a small for loop.
#include <iostream>
#include <string>
#include <sstream>
std::string cmd(const std::size_t N)
{
std::ostringstream os;
os << "start:";
for(std::size_t n = 1; n <= N; ++n) os << "Pdc" << n << ";";
return os.str();
}
int main()
{
std::cout << cmd(3ul);
return 0;
}

I want to store the following line into a string array in C++. How can I do it?

I want to make a string array in C++ which holds 0000, 0001, 00002, 0003 and so on up to 9999. Is there any way to implement this with loop. I do not want to take input manually. I want something like this.
for(i=0;i<10000;i++)
str[i] = i;
https://ideone.com/4kayTz
#include <iostream>
#include <vector>
#include <string>
#include <sstream>
#include <iomanip>
int main() {
std::vector<std::string> str(10000);
std::stringstream ss;
ss << std::setfill('0');
for (int i = 0; i < 10000; i++) {
ss << std::setw(4) << i;
str[i] = ss.str();
ss.str(""); // Reset/make empty the string stream.
std::cout << str[i] << std::endl;
}
return 0;
}

How to print the fractional part of float number while converting to string

I have a code which will convert the float value to string, i have written like below
#include <iostream>
#include <string>
#include <sstream>
using namespace std;
int main() {
float myFloat= 10.80;
std::ostringstream ss;
ss << myFloat;
cout<<"value = " << ss.str();
std::string s(ss.str());
cout<<"value = " << s;
return 0;
}
But the problem is when my value is 10.66 its coming 10.66 but when its 10.80 its coming like 10.8 or when its 10.00 its coming 10 only .
How can i print the complete value
Try this code .
Use the setprecision function with '2' .
#include <iostream>
#include <string>
#include <sstream>
#include <iomanip>
using namespace std;
int main() {
float myFloat= 10.80;
stringstream stream;
stream << fixed << setprecision(2) << myFloat;
string s = stream.str();
cout<<"value = " << s;
return 0;
}
The trailing zeros are only kept if you set either fixed or scientific mode.
#include <iostream>
#include <iomanip>
using namespace std;
int main()
{
double x = 4.2;
cout << fixed << setprecision(2);
cout << x << endl;
return 0;
}
It seems you want something like below.
#include <iostream>
#include <iomanip>
#include <string>
#include <sstream>
using namespace std;
int main() {
float myFloat= 10.80;
std::ostringstream ss;
ss << fixed << setprecision(2) << myFloat;
cout<<"value = " << ss.str();
std::string s(ss.str());
cout<<"value = " << s;
}
Probably the least complicated way would be to use printf instead of std::cout. There you can specifically specify how many digits are to be displayed.
#include "stdio.h"
printf("%3.2f",myfloat);
where 3 is the # of digits before and 2 the # of digits after the dot, either can be left out. Append '\n' to the string if you want a new line.
EDIT: Ok, I did not know about setprecision(2).

What's the equivalent of cout for output to strings?

I should know this already but... printf is to sprintf as cout is to ____? Please give an example.
It sounds like you are looking for std::ostringstream.
Of course C++ streams don't use format-specifiers like C's printf()-type functions; they use manipulators.
Example, as requested:
#include <sstream>
#include <iomanip>
#include <cassert>
std::string stringify(double x, size_t precision)
{
std::ostringstream o;
o << std::fixed << std::setprecision(precision) << x;
return o.str();
}
int main()
{
assert(stringify(42.0, 6) == "42.000000");
return 0;
}
#include <iostream>
#include <sstream>
using namespace std;
int main()
{
ostringstream s;
s.precision(3);
s << "pi = " << fixed << 3.141592;
cout << s.str() << endl;
return 0;
}
Output:
pi = 3.142
Here's an example:
#include <sstream>
int main()
{
std::stringstream sout;
sout << "Hello " << 10 << "\n";
const std::string s = sout.str();
std::cout << s;
return 0;
}
If you want to clear the stream for reuse, you can do
sout.str(std::string());
Also look at the Boost Format library.
std::ostringstream
You can use this to create something like the Boost lexical cast:
#include <sstream>
#include <string>
template <typename T>
std::string ToString( const T & t ) {
std::ostringstream os;
os << t;
return os.str();
}
In use:
string is = ToString( 42 ); // is contains "42"
string fs = ToString( 1.23 ) ; // fs contains something approximating "1.23"
You have a little misunderstanding for the concept of cout. cout is a stream and the operator << is defined for any stream. So, you just need another stream that writes to string in order to output your data. You can use a standard stream like std::ostringstream or define your own one.
So your analogy is not very precise, since cout is not a function like printf and sprintf