Parsing Numeric Data

Discussion in 'C++' started by Mike Copeland, Oct 16, 2012.

  1. 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
    Mike Copeland, Oct 16, 2012
    #1
    1. Advertising

  2. Mike Copeland

    Ian Collins Guest

    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
    Ian Collins, Oct 16, 2012
    #2
    1. Advertising

  3. Mike Copeland

    Jorgen Grahn Guest

    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 .
    Jorgen Grahn, Oct 16, 2012
    #3
  4. Mike Copeland

    Luca Risolia Guest

    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> readints(istream& in) {
    IStreamExceptions e(in, ios_base::failbit | ios_base::badbit);
    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;
    }
    Luca Risolia, Oct 16, 2012
    #4
  5. Mike Copeland

    tes Guest

    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
    tes, Dec 7, 2012
    #5
  6. Mike Copeland

    Jorgen Grahn Guest

    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 .
    Jorgen Grahn, Dec 7, 2012
    #6
    1. Advertising

Want to reply to this thread or ask your own question?

It takes just 2 minutes to sign up (and it's free!). Just click the sign up button to choose a username and then you can ask your own questions on the forum.
Similar Threads
  1. luna
    Replies:
    1
    Views:
    13,811
    Kevin Spencer
    Feb 6, 2004
  2. Replies:
    5
    Views:
    912
    X-Centric
    Jun 30, 2005
  3. darrel
    Replies:
    4
    Views:
    793
    darrel
    Jul 19, 2007
  4. jobs

    int to numeric numeric(18,2) ?

    jobs, Jul 21, 2007, in forum: ASP .Net
    Replies:
    2
    Views:
    936
    =?ISO-8859-1?Q?G=F6ran_Andersson?=
    Jul 22, 2007
  5. Mike Copeland

    Parsing Numeric Data

    Mike Copeland, Nov 8, 2012, in forum: C++
    Replies:
    2
    Views:
    357
    Jorgen Grahn
    Nov 12, 2012
Loading...

Share This Page