How would I convert a string to "boost::multiprecision::cpp_int"?
Additionally, I have a .txt file with 100 numbers each of 50 digits and I use ifstream to read them line by line into a string array. How can I convert each string from the array into a cpp_int, then add all the 100 numbers and get the sum?
To convert a single string, use the cpp_intconstructor: cpp_int tmp("123");.
For the text file case, read each number in a loop as a std::string via std::getline, then emplace back in a std::vector<cpp_int>. Then use the latter to compute your sum. Example:
#include <fstream>
#include <iostream>
#include <string>
#include <vector>
#include <boost/multiprecision/cpp_int.hpp>
using namespace boost::multiprecision;
int main()
{
std::vector<cpp_int> v;
std::fstream fin("in.txt");
std::string num;
while(std::getline(fin, num))
{
v.emplace_back(num);
}
cpp_int sum = 0;
for(auto&& elem: v)
{
std::cout << elem << std::endl; // just to make sure we read correctly
sum += elem;
}
std::cout << "Sum: " << sum << std::endl;
}
PS: you may do it without a std::vector, via a temporary cpp_int that you construct inside the loop and assign it to sum:
std::string num;
cpp_int sum = 0;
while(std::getline(fin, num))
{
cpp_int tmp(num);
sum += tmp;
}
std::cout << "Sum: " << sum << std::endl;
Related
I have a csv file in Excel that has a column of double data. I am trying to read that column and store the values in a vector variable using a while loop. I tried to use getline and then convert them into a double using stod.
The column has more values, but this is how the csv file looks like:
A
B
51.32
53.62
#include <iostream>
#include <fstream>
#include <vector>
using namespace std;
int main()
{
ifstream myFile("CData.csv");
int i= 0;
string val;
std::vector<double> y;
while (getline(myFile, val, ',')) {
y.push_back(stod(val));
cout << "test: " << y.at(i);
i++;
}
return 0;
}
I'm not sure what I'm doing wrong. Somehow, there is no output on the console app. I tried it with string ang it worked but when I try to convert to a double, it doesn't. Is there another way to do this, or did I miss something in the code? Thanks, I'm new to coding.
You need to first parse the line and then look at the line for comma separated data. Also you need to chek if data is digits or not.
Here is an example:
#include <iostream>
#include <fstream>
#include <vector>
#include <stdio.h>
#include <stdlib.h>
#include <sstream>
using namespace std;
int main()
{
ifstream myFile("CData.csv", std::ios::in);
int i= 0;
string val;
std::string line;
std::vector<double> y;
while (getline(myFile, line))
{
std::stringstream sstr(line);
while (getline(sstr, val, ','))
{
bool flag = true;
for (auto c : val)
if (!isdigit(c))
flag = false;
if (flag){
y.push_back( std::stod(val));
std::cout << "number: " << y.at(i) << std::endl;
i++;
}
else std::cout << "not number: " << val << std::endl;
}
}
return 0;
}
Good luck!
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.
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 am pretty new to c++. I am trying to read a file in line by line and store the input into several arrays.
Because I don't know the size of input file, I have this to get the number of lines in the file
while (std::getline(inputFile, line)){
++numOfLines;
std::cout << line << std::endl;
}
Now I want to use the numOfLines as the size of arrays, but i cannot get it run by having this
std::string *firstName= new std::string[numOfLines];
std::string *lastName= new std::string[numOfLines];
for (int i = 0; i < numOfLines; ++i)
{
line >> firstName[i];
}
I guess it is because it has reached the end of the file after the while loop. But I do not know how to solve this problem. Is there a way to scan the input file in and store the value into array at the same time?
If you use std::vector you don't need to know ahead the lines count. You can use vector method push_back to insert new elements into it. Try use something like this:
#include <fstream>
#include <iostream>
#include <vector>
#include <string>
using namespace std;
int main()
{
std::vector<std::string> first_names;
std::string line;
ifstream input_file;
while (std::getline(input_file, line)){
first_names.push_back(line);
}
for (size_t i = 0; i < first_names.size(); i++) {
std::cout << first_names[i] << std::endl;
}
return 0;
}
I don't know if you have ever taken a course related to Data Structures & Algorithms,
in which you will learn to use Containers (such as:
vector,
deque,
list, etc.) instead of Primitive Data Structures.
Please notice that although the follow example chooses vector as its container, it could vary according to different contexts. Say you are handling gigantic mount of data, you might want to use list instead`1,2,3.
#include <fstream>
#include <iostream>
#include <vector>
#include <string>
// alias long type
// #see: https://en.cppreference.com/w/cpp/language/type_alias
using NameVector = std::vector<std::string>;
int handleLine(std::string line, NameVector &firstNames)
{
// TODO implement your line handler here
firstNames.push_back(line);
return 0;
}
int handleFile(std::ifstream inputFile, NameVector &firstNames)
{
std::string line;
for (int lineNum = 1;
// invoke `good` to check if there is any error
inputFile.good()
&&
std::getline(inputFile, line);
lineNum++)
{
std::cout << "Current line number : (" << lineNum << ")" << std::endl;
std::cout << "Current line content: (" << line << ")" << std::endl;
handleLine(line, &firstNames);
}
return 0;
}
int main()
{
std::string path; // = R"(HERE GOES YOUR FILE PATH)";
// Using **Raw string**
std::ifstream inputFile { path }; // Initialize `inputFile`
NameVector firstNames;
handleFile(inputFile, firstNames);
for (auto firstName : firstNames)
{
std::cout << firstName << std::endl;
}
return 0;
}
I am trying to create an array of String that contain numbers. These numbers are the names of folders that I need to access. Currently I am declaring it as shown below:
String str1[] = { "001", "002", "003", "004", "005", "006", "007", "008", "009", "010", "011", "012", "013", "014", "015", "016", "017", "018", "019", "020", };
I have 124 folders and naming them in such fashion is tedious. Is there a better way to do this? I am working with C++.
You can use stringstreams and set the format options to fill the integer to a certain number of characters and set the filling character.
Edit: Ok my code doesn't begin with 1 but 0, but I'm sure you can figure that out :)
#include <iostream>
#include <string>
#include <sstream>
#include <iomanip>
#include <vector>
using namespace std;
int main()
{
std::vector<std::string> strs;
for (int i = 0; i < 124; i++)
{
std::ostringstream os;
os << std::setfill('0') << std::setw(3) << i;
strs.push_back(os.str());
}
for (const auto& s : strs)
{
std::cout << s << "\n";
}
}
Live example: http://ideone.com/TEV2iq
use a stringstream and for loop.
Example:
uint32_t t150()
{
std::vector<std::string> strVec; // i.e. String str1[]
for (int i=1; i<125; ++i)
{
std::stringstream ss;
ss << std::setw(3) << std::setfill('0') << i;
strVec.push_back(ss.str());
}
for (int i=0; i<124; ++i)
std::cout << strVec[i] << std::endl;
return(0);
}
An alternative is something like:
std::string t150b(int i) {
std::stringstream ss;
ss << std::setw(3) << std::setfill('0') << i;
return (ss.str());
}
// not tested, and no range check
which returns the formatted string for the value i ... I imagine you have the loop at some higher level code.
Another alternative is to skip the vector, just build the string with white spaces between ... then fetch them like you fetch any file item ...
void t150c(std::stringstream& ss)
{
for (int i=1; i<125; ++i) {
ss << std::setw(3) << std::setfill('0') << i << " ";
// white space between values -------------------^^
}
}
Usage example:
{
std::stringstream ss;
t150c(ss); // 'fill' stream with desired strings
do {
if(ss.eof()) break;
std::string s;
ss >> s; // extract string one at a time
std::cout << s << std::endl; // and use
}while(1);
}
std::string str1[124];
for(int i = 1; i <= 124; i++){
str1[i-1] = convertTo3Digit(i);
}
Then just write the convertTo3Digit function to take the numerical value and format it into a 3-digit string.
Another less elegant way would be to format a column in excel to be three-digit numbers and generate 001-124 and then copy-paste into your static initializer. You can use regex to add the quotes and commas.