Velocity Reviews (http://www.velocityreviews.com/forums/index.php)
-   C++ (http://www.velocityreviews.com/forums/f39-c.html)
-   -   Parsing Numeric Data (http://www.velocityreviews.com/forums/t953459-parsing-numeric-data.html)

 Mike Copeland 10-16-2012 06:05 PM

Parsing Numeric Data

I'm looking for a technique to parse a series of numeric values from
a line of input. For example, I have the following data lines:

1 2 37 36 4 7 5 6 8 9 10 20 16
601 1100 11 3900 0 0 Starting Values

I want to extract the numeric values from each line, but as can be
seen there are different numbers of values and one line has non-numeric
data that I wish to ignore. Currently I use strtok to (laboriously)
work through each data line, but I assume there must be better ways to
extract such data (and store it into an array or STL container) than
that.
Any thoughts? TIA

 Ian Collins 10-16-2012 07:13 PM

Re: Parsing Numeric Data

On 10/17/12 07:05, Mike Copeland wrote:
> I'm looking for a technique to parse a series of numeric values from
> a line of input. For example, I have the following data lines:
>
> 1 2 37 36 4 7 5 6 8 9 10 20 16
> 601 1100 11 3900 0 0 Starting Values
>
> I want to extract the numeric values from each line, but as can be
> seen there are different numbers of values and one line has non-numeric
> data that I wish to ignore. Currently I use strtok to (laboriously)
> work through each data line, but I assume there must be better ways to
> extract such data (and store it into an array or STL container) than
> that.
> Any thoughts? TIA

One simple approach is to read a line, then use the line to build a
stringstream and extract the data from there. For example:

#include <iostream>
#include <fstream>
#include <sstream>
#include <vector>

int main( int argc, char** argv )
{
typedef std::vector<int> LineOfData;
typedef std::vector<LineOfData> LinesOfData;

LinesOfData lines;

std::ifstream fin(argv[1]);

while( fin )
{
std::string s;

std::getline( fin, s );

if( fin )
{
std::istringstream in(s);
LineOfData line;

while( in )
{
int n;
in >> n;

if( in )
{
line.push_back(n);
}
}

lines.push_back(line);
}
}

for( LinesOfData::const_iterator line = lines.begin();
line != lines.end(); ++line )
{
for( LineOfData::const_iterator n = line->begin();
n != line->end(); ++n )
{
std::cout << *n << ' ';
}
std::cout << std::endl;
}
}

--
Ian Collins

 Jorgen Grahn 10-16-2012 07:42 PM

Re: Parsing Numeric Data

On Tue, 2012-10-16, Mike Copeland wrote:
> I'm looking for a technique to parse a series of numeric values from
> a line of input. For example, I have the following data lines:
>
> 1 2 37 36 4 7 5 6 8 9 10 20 16
> 601 1100 11 3900 0 0 Starting Values
>
> I want to extract the numeric values from each line, but as can be
> seen there are different numbers of values and one line has non-numeric
> data that I wish to ignore. Currently I use strtok to (laboriously)
> work through each data line, but I assume there must be better ways to
> extract such data (and store it into an array or STL container) than
> that.

I don't see what's hard about it. Here's one approach (but untested,
and you'll have to read the documentation to ensure that the behavior
is really the one you want).

void numbers(const char* s, std::vector<unsigned>& v)
{
while(1) {
char* e;
unsigned n = strtoul(s, &e, 10);
if(e==s) break;
if(!e) break;
v.push_back(n);
s = e;
}
}

/Jorgen

--
// Jorgen Grahn <grahn@ Oo o. . .
\X/ snipabacken.se> O o .

 Luca Risolia 10-16-2012 09:34 PM

Re: Parsing Numeric Data

On 16/10/2012 20:05, Mike Copeland wrote:
> I'm looking for a technique to parse a series of numeric values from
> a line of input. For example, I have the following data lines:
>
> 1 2 37 36 4 7 5 6 8 9 10 20 16
> 601 1100 11 3900 0 0 Starting Values
>
> I want to extract the numeric values from each line, but as can be
> seen there are different numbers of values and one line has non-numeric
> data that I wish to ignore. Currently I use strtok to (laboriously)
> work through each data line, but I assume there must be better ways to
> extract such data (and store it into an array or STL container) than
> that.
> Any thoughts? TIA

#include <iostream>
#include <sstream>
#include <vector>

using namespace std;

class IStreamExceptions { // RAII
public:

IStreamExceptions(istream& is, const ios_base::iostate state)
: is_(is), old_state(is.exceptions()) {
is_.exceptions(state);
}

~IStreamExceptions() {
is_.exceptions(old_state);
}
private:
istream& is_;
const ios_base::iostate old_state;
};

vector<int> v;
for (;;)
try {
int i;
in >> i;
v.push_back(i);
} catch (ios_base::failure f) { // ignore
if (in.eof())
return v;
in.clear();
in.ignore();
}
}

int main(int argc, char** argv) {
istringstream is("345 string 678 90 90 x");
for (const int& e : readints(is)) // or cin
cout << e << '\n';
return 0;
}

 tes 12-07-2012 05:58 PM

Re: Parsing Numeric Data

On 16.10.2012 20:05, Mike Copeland wrote:
> I'm looking for a technique to parse a series of numeric values from
> a line of input. For example, I have the following data lines:
>
> 1 2 37 36 4 7 5 6 8 9 10 20 16
> 601 1100 11 3900 0 0 Starting Values
>
> I want to extract the numeric values from each line, but as can be
> seen there are different numbers of values and one line has non-numeric
> data that I wish to ignore. Currently I use strtok to (laboriously)
> work through each data line, but I assume there must be better ways to
> extract such data (and store it into an array or STL container) than
> that.
> Any thoughts? TIA
>

I really dont understand the more difficult solutions posted so far. Use
a [boost|std]::regex_iterator

 Jorgen Grahn 12-07-2012 08:03 PM

Re: Parsing Numeric Data

On Fri, 2012-12-07, tes wrote:
> On 16.10.2012 20:05, Mike Copeland wrote:
>> I'm looking for a technique to parse a series of numeric values from
>> a line of input. For example, I have the following data lines:
>>
>> 1 2 37 36 4 7 5 6 8 9 10 20 16
>> 601 1100 11 3900 0 0 Starting Values
>>
>> I want to extract the numeric values from each line, but as can be
>> seen there are different numbers of values and one line has non-numeric
>> data that I wish to ignore. Currently I use strtok to (laboriously)
>> work through each data line, but I assume there must be better ways to
>> extract such data (and store it into an array or STL container) than
>> that.
>> Any thoughts? TIA
>>

>
> I really dont understand the more difficult solutions posted so far. Use
> a [boost|std]::regex_iterator

If you don't understand my strtoul()-based one or Ian Collins'
iostreams-based one, you should read up on those subjects. They seem
very straightforward to me.

Or perhaps you meant to say "I don't understand why they didn't
recommend regexes instead"? In my case, because I haven't used Boost
yet, and boost.regex seems overly complicated at a quick glance.

/Jorgen

--
// Jorgen Grahn <grahn@ Oo o. . .
\X/ snipabacken.se> O o .

 All times are GMT. The time now is 04:29 AM.