I would like to read an input file in C++, for which the structure (or lack of) would be something like a series of lines with text = number, such as
input1 = 10
input2 = 4
set1 = 1.2
set2 = 1.e3
I want to get the number out of the line, and throw the rest away. Numbers can be either integers or doubles, but I know when they are one or other.
I also would like to read it such as
input1 = 10
input2=4
set1 =1.2
set2= 1.e3
so as to be more robust to the user. I think this means that it shouldn't be red in a formatted fashion.
Anyway, is there a smart way to do that?
I have already tried the following, but with minimal knowledge of what I've been doing, so the result was as expected... no success.
#include <stdio.h>
#include <stdlib.h>
#include <float.h>
#include <math.h>
#include <iostream>
#include <fstream>
#include <iomanip>
#include <cstdlib>
#include <boost/lexical_cast.hpp>
#include <string>
using namespace std;
using namespace boost;
int main(){
string tmp;
char temp[100];
int i,j,k;
ifstream InFile("input.dat");
//strtol
InFile.getline(temp,100);
k=strtol(temp,0,10);
cout << k << endl;
//lexical_cast
InFile.getline(temp,100);
j = lexical_cast<int>(temp);
cout << j << endl;
//Direct read
InFile >> tmp >> i;
cout << i << endl;
return 0;
}
now that you are already using boost with lexical_cast, just parse each line with boost::split() and boost::is_any_of() into 1 2-element vector, with token_compress turned on.
the following code illustrates the parse, but skips the numeric conversion, which could be solved easily with boost lexical_cast.
Off the top of my head:
C FTW (modified to handle doubles)
There are already some fine solutions here. However, just to throw it out there, some comments implied that Boost Spirit is an inappropriate solution for this problem. I'm not sure I completely disagree. However, the following solution is very terse, readable (if you know EBNF) and error-tolerant. I'd consider using it.
Simply read one line at a time.
Then split each line on the '=' sign. Use the stream functionality do the rest.
With error checking:
Just tested this... it works, and doesn't require anything outside of the C++ standard library.
EDIT: I just read the original question and noticed I'm not producing an exact answer. If you don't care about the key names, juts discard them. Also, why do you need to identify the difference between integer values and floating-point values? Is
1000
an integer or a float? What about1e3
or1000.0
? It's easy enough to check if a given floating-point value is integral, but there is a clas of numbers that are both valid integers and valid floating-point values, and you need to get into your own parsing routines if you want to deal with that correctly.