This code reads the first line of some data I have in .txt file,
this first line value is '6.0', im reading the rest of the data later on in a loop, my question is how can I convert 'line' (a string) to a double (I would call 'instances') so that I can use it later in the program? It needs to be a double so I can do some calculations later with other double types. Probably a very simple solution, thanks in advance.
NOTE: I have tried using:
#include <stdlib.h>
double instances = atof(line.c_str());
But it returns 0 not the correct value '6.0'
#include <iostream>
#include <string>
#include <fstream>
using namespace std;
int main()
{
string line;
ifstream infile ("data2.txt");
if (infile.is_open())
{
getline (infile,line);
cout << line << '\n';
infile.close();
}
...
}
You have lots of options. These all have different ways of checking the output for validity. Some of them throw an exception if line doesn't contain a double, some give a return value that you could check. Whichever one is best for you depends entirely on your program.
C++11 introduced std::stod:
double instances = std::stod(line);
Before that, there's the confusingly named std::atof that still returns a double:
double instances = std::atof(line.c_str());
Or you could use a std::istringstream's operator>> to extract a double:
std::istringstream iss(line);
double instances;
iss >> instances;
Or you could use std::sscanf:
double instances;
std::sscanf(line.c_str(), "%lf", &instances);
Or you could use Boost.Lexical_Cast:
double instances = boost::lexical_cast<double>(line);
Related
I have a set of data consisting of two columns, and the code reads the horizontal lines, including the first and second column. Can I make the code read only the first column? or the second column?
This is the code :
#include <iostream>
#include <stdio.h>
#include <cstdlib>
#include <cmath>
#include<iomanip>
#include<random>
#include<string>
#include<fstream>
using namespace std;
int main() {
fstream MyFile;
MyFile.open("DOS.txt", ios::in); // read
if (MyFile.is_open()) {
string line;
while (getline(MyFile, line)) {
cout << line << endl;
}
MyFile.close();
}
system("pause>0");
}
Here are the data
-8.44369507 2.65307838E-41
-8.43369484 6.90195008E-37
-8.42369461 9.69609381E-33
-8.41369534 7.34995534E-29
-8.40369511 3.01151891E-25
-8.39369488 6.6639834E-22
-8.38369465 7.96475875E-19
-8.37369442 5.1424519E-16
-7.8936944 0.061314974
-7.88369417 0.059985429
-7.87369394 0.0593142845
The data are longer than this but this is a part of it .
Since your data is space delimited, you can use the plain stream extractor operator >> to read from a stream directly into floating point variables.
For example
std::istringstream iss(line);
double val1, val2;
iss >> val1 >> val2;
If you have many more values on each line, you can use an input stream iterator to initialize a vector:
std::istringstream iss(line);
std::vector<double> values(std::istream_iterator<double>(iss),
std::istream_iterator<double>());
After this the vector will contain all values from the current line. You can then use normal vector indexing to get the specific values you need.
I am trying to read this csv file, let's call it "file.csv", and I'm trying to put it into a vector of double.
This csv contains numbers like:
755673.8431514322,
684085.6737614165,
76023.8121728658,
...
I tried using stringstream, and it successfully input these number to the vector but the input numbers is not like I wanted. Instead, the inputted numbers are
7556373, 684085, 76023.8
How can I read the whole digits without throwing any of it away?
This is my code
vector<long double> mainVector;
int main()
{
ifstream data;
data.open("file.csv");
while (data.good())
{
string line;
stringstream s;
long double db;
getline(data, line, ',');
s << line;
s >> db;
mainVector.push_back(db);
}
}
How to read the whole digits without throwing any of it.
As #user4581301 mentioned in the comments, I guess you are missing std::setprecision() while outputting.
However, you do not need std::stringstream to do the job. Convert line(which is a string directly to double using std::stold and place into the vector directly as follows.
That being said, use of std::stold will make sure not to have wrong input to the vector, by throwing std::invalid_argument exception, if the conversion from string to double was unsuccessful. (Credits to #user4581301)
#include <iostream>
#include <fstream>
#include <vector> // std::vector
#include <string> // std:: stold
#include <iomanip> // std::setprecision
int main()
{
std::vector<long double> mainVector;
std::ifstream data("file.csv");
if(data.is_open())
{
std::string line;
while(std::getline(data, line, ','))
mainVector.emplace_back(std::stold(line));
}
for(const auto ele: mainVector)
std::cout << std::setprecision(16) << ele << std::endl;
// ^^^^^^^^^^^^^^^^^^^^
return 0;
}
I have an input file which I'm reading in with the basic myFile >> variable since I know the format and the format will always be correct. The file I'm reading in is formatted as instruction <num> <num> and to make >> work, I'm reading everything in as a string. If I have 3 variables, one to take in each piece of the line, how can I then turn string <1> (for example) into int 1? I know the string's first and last characters are brackets which need to be removed, then I could cast to an int, but I'm new to C++ and would like some insight on the best method of doing this (finding and removing the <>, then casting to int)
use stringstream
#include <string>
#include <sstream>
#include <iostream>
int main() {
std::string str = "<1>";
int value;
std::stringstream ss(str);
char c;
ss >> c >> value >> c;
std::cout << value;
}
First to get the middle character out you can just do char myChar = inputString.at(1);. Then you can do int myInt = (int)myChar;
Even if you remove the <> characters, your still importing the file content into a string using >> so you still need to cast it to an int. If you have only 1 value, you can follow what Nicholas Callahan wrote in the previous answer, but if you have multiple characters you want to read as int, you dont have a choice but to cast.
You can also resort to sscanf.
#include <cstdio>
#include <iostream>
#include <string>
int main()
{
std::string str = "<1234>";
int value;
sscanf(str.c_str(), "<%d>", &value);
std::cout << value << std::endl;
}
psedo code:
#include <iostream>
#include <fstream>
#include <sstream>
#include <string>
using namespace std;
int main() {
string line;
double beta[250];
char Batob[250], eq[250];
ifstream myfile("iter1/HMMemit0.txt");
if (myfile.is_open())
{
int i = 0;
while (getline(myfile, line))
{
istringstream iss(line);
if (!(iss >> Batob[i] >> eq[i] >> beta[i])){ //it store only B in Batob[i], but i want to save B00 in Batob[i], = in eq[i], and 0.524671 in beta[250]
break;
}
i++;
}
myfile.close();
}
else cout << "Unable to open file";
return 0;
}
my data stored in HMMemint0 like this
B00 = 0.524671
B01 = 0.001000
B02 = 0.001000
B10 = 0.001097
B11 = 0.001000
B12 = 0.001000
i want to read a line and save each term in each variable like B00 saved in name[i], and 0.001000 in beta[i].
and then, write it in this 0.524671(B00's value) 0.001097(B10's value) order like this
0.524671 0.001097
0.001000 0.001000
0.001000 0.001000
How can i do it? please help me.
You are having a char array for "BXX"s, whereas you want strings. Basically, you want a string array, or even vector. The problem is that only 'B' will be read from "BXX" into your first parameter.
This code works for me:
#include <iostream>
#include <fstream>
#include <sstream>
#include <string>
using namespace std;
int main() {
string line;
double beta[250];
string Batob[250];
char eq[250];
ifstream myfile("iter1/HMMemit0.txt");
if (myfile.is_open())
{
int i = 0;
while (getline(myfile, line))
{
istringstream iss(line);
iss >> Batob[i] >> eq[i] >> beta[i];
i++;
}
myfile.close();
}
else cout << "Unable to open file";
return 0;
}
Disclaimer: I was just fixing your code with the least impact, but of course if you start using proper C++ containers like vector, the i variable could be easily eliminated as the elements and the index would be maintained automatically.
Also, since you are using the equal sign ('=') all the time for the char array, it is a bit needless waste of memory, which could be severe in case of a big file.
I would say, using an associate container in the future would be even more productive for your BXX keys and their corresponding values on the right side.
Batob is an array of characters, so Batob[i] is a single character. That's why your program reads only one character. If you want to read 250 strings of characters you need to make room for them. The simplest (not necessarily the best, however) method is to declare an array like char Batob[250][100] – this would be an array of 250 arrays, 100 characters each. Then Batob[i] is a 100-chars array and you can input a string with iss >> Batob[i].
i would like to request some help on theory part, so grind those gears, here it comes
I want to load a file into my program, which looks something like this:
0,10,10#0,100,40...
Okay what i now want to do is to take out every comma separated number and send it through my function
void func( int, float, float );
The hashtag means it's a new block, so it would be sent like func(0,10,10) and after that it would send func(0,100,40) and so on.
I was thinking to check every char until i meet ',' and after that put it in a vector, and continue that until the '#' is met. Then it would fire away my function (like func(v[0],v[1],v[2]) and then just do the same thing over and over until EOF!
Is this a good way to go? Have any better ideas? Those numbers can also get very large later on, so i don't know how much memory i need (therefor the vector). Or should i just go with 3 temp ints and floats and then fire the function and start over!
Going char by char and using a state machine like you suggested is the fastest way.
However the easiest way is first to split by the # and then for each result string split by ,.
You can use boost library to do the string split.
#include <fstream>
#include <ostream>
#include <istream>
#include <stdexcept>
void func( std::vector<float> &numbers )
{}
int main() {
std::ifstream myfile("myfile.txt");
float number;
char seperator;
std::vector<float> numbers;
while( myfile >> number) { //read number
numbers.push_back(number); //and remember it
if (!(myfile >> seperator) || seperator == "#") { //if # or EOF or error
func(numbers); //run function
numbers.clear(); //and start over
}
} //only gets here at EOF or malformed file
return 0;
}
Very simple, fast, and easy.
If you're certain the file starts with the first int of a group of three
ifstream fin("foo.csv");
string str;
stringstream s_str;
while(!fin.eof())
{
int a;
float b,c;
getline(fin,str,',');
s_str.str(str);
s_str >> a;
getline(fin,str,',');
s_str.str(str);
s_str >> b;
getline(fin,str,'#');
s_str.str(str);
s_str >> c;
}
should work. (I haven't compiled it so there might be typos etc)