reading a mixed file

Discussion in 'C++' started by adpsimpson, Jul 29, 2003.

  1. adpsimpson

    adpsimpson Guest

    Hi, I have a file which I wish to read from C++. The file, created by
    another programme, contains both text and numbers, all as ascii (it's
    a .txt file). A sample of the file is shown below:

    << LEDAR V1.3 - Real Time Detection >>

    <LEFT 144>
    <TOP 165>
    <RIGHT 265>
    <BOTTOM 376>
    <STEP 4>
    <Kx 2.13068>
    <Ky 0.882353>
    <Detection 1>

    25600055 1
    299 299 299 299 299 297 297 297 297 297 297 297 297
    299 299 299 299 299 297 297 297 297 297 297 297 297
    299 299 299 299 299 297 297 297 297 297 297 297 297
    299 299 299 299 299 297 297 297 297 297 297 297 297

    26800055 2
    300 300 300 300 299 297 297 297 297 298 299 299 299
    300 300 300 300 299 297 297 297 297 298 299 299 299
    300 300 300 300 299 297 297 297 297 298 299 299 299
    300 300 300 300 299 297 297 297 297 298 299 299 299

    28000055 3
    300 300 300 300 301 301 301 300 301 301 301 301 300
    300 300 300 300 301 301 301 300 301 301 301 301 300
    300 300 300 300 301 301 301 300 301 301 301 301 300
    300 300 300 300 301 301 301 300 301 301 301 301 300

    Of the long lines, I want to read one line from each group, and ignore
    everything else. I have relatively little experience with C++, and can
    not find a suitable way to do this. Any suggestions? Please type a
    small bit of sample code to show how suggested functions should be
    used.

    Thanks! Andrew
     
    adpsimpson, Jul 29, 2003
    #1
    1. Advertising

  2. adpsimpson

    Adam Fineman Guest

    adpsimpson wrote:
    > Hi, I have a file which I wish to read from C++. The file, created by
    > another programme, contains both text and numbers, all as ascii (it's
    > a .txt file). A sample of the file is shown below:
    >
    > << LEDAR V1.3 - Real Time Detection >>
    >
    > <LEFT 144>
    > <TOP 165>
    > <RIGHT 265>
    > <BOTTOM 376>
    > <STEP 4>
    > <Kx 2.13068>
    > <Ky 0.882353>
    > <Detection 1>
    >
    > 25600055 1
    > 299 299 299 299 299 297 297 297 297 297 297 297 297
    > 299 299 299 299 299 297 297 297 297 297 297 297 297
    > 299 299 299 299 299 297 297 297 297 297 297 297 297
    > 299 299 299 299 299 297 297 297 297 297 297 297 297
    >
    > 26800055 2
    > 300 300 300 300 299 297 297 297 297 298 299 299 299
    > 300 300 300 300 299 297 297 297 297 298 299 299 299
    > 300 300 300 300 299 297 297 297 297 298 299 299 299
    > 300 300 300 300 299 297 297 297 297 298 299 299 299
    >
    > 28000055 3
    > 300 300 300 300 301 301 301 300 301 301 301 301 300
    > 300 300 300 300 301 301 301 300 301 301 301 301 300
    > 300 300 300 300 301 301 301 300 301 301 301 301 300
    > 300 300 300 300 301 301 301 300 301 301 301 301 300
    >
    > Of the long lines, I want to read one line from each group, and ignore
    > everything else.


    I assumed in the code below that you could assume that the header will
    always be the same number of lines. If that's not the case, then you
    should write some type of function that will look for a sentinal or
    whatever is appropriate. I also assumed that each group will have four
    long lines.

    Some other points about the code: note that the return types of the two
    helper functions are string and vector<int>. Returning large types by
    value requires creating and copying a temporary object. This, in some
    applications is an unnecessary overhead, but it probably won't be a
    significant bottleneck in this case.

    /////////////////////////////////////////////
    #include <iostream>
    #include <string>
    #include <vector>
    #include <iterator>
    #include <sstream>

    using namespace std;

    string read_group();
    vector<int> parse_line(const string&);

    int
    main()
    {
    string junk;

    const int LEADING_TEXT = 11;

    for (int i = 0; i < LEADING_TEXT; ++i)
    getline(cin, junk);

    int line_number = 1;
    while (true) {
    string line = read_group();
    if (line == "")
    break;

    cout << "line " << line_number << ": \'" << line << "\'\n";

    vector<int> value = parse_line(line);
    cout << "{ ";
    copy(value.begin(), value.end(), ostream_iterator<int>(cout, " "));
    cout << " }\n";
    }

    return 0;
    }

    string
    read_group()
    {
    const int LINES_PER_GROUP = 4;
    string junk;
    getline(cin, junk); // '25600055 1'
    if (!cin)
    return "";

    string line;
    getline(cin, line); // this is the line of interest

    for (int i = 0; i < LINES_PER_GROUP; ++i)
    getline(cin, junk); // 3 more lines, plus a blank.
    // The blank may not exist after
    // the last group, but you may be
    // able to ignore that.

    return line;
    }


    vector<int>
    parse_line(const string& line)
    {
    vector<int> v;
    int i;
    istringstream iss(line);

    while (iss >> i)
    v.push_back(i);

    return v;
    }
    ////////////////////////////////////////


    --
    Adam Fineman

    (Reverse domain name to reply.)
     
    Adam Fineman, Jul 29, 2003
    #2
    1. Advertising

  3. adpsimpson

    Chris Theis Guest

    "adpsimpson" <> wrote in message
    news:...
    > Hi, I have a file which I wish to read from C++. The file, created by
    > another programme, contains both text and numbers, all as ascii (it's
    > a .txt file). A sample of the file is shown below:
    >
    > << LEDAR V1.3 - Real Time Detection >>
    >
    > <LEFT 144>
    > <TOP 165>
    > <RIGHT 265>
    > <BOTTOM 376>
    > <STEP 4>
    > <Kx 2.13068>
    > <Ky 0.882353>
    > <Detection 1>
    >
    > 25600055 1
    > 299 299 299 299 299 297 297 297 297 297 297 297 297
    > 299 299 299 299 299 297 297 297 297 297 297 297 297
    > 299 299 299 299 299 297 297 297 297 297 297 297 297
    > 299 299 299 299 299 297 297 297 297 297 297 297 297
    >
    > 26800055 2
    > 300 300 300 300 299 297 297 297 297 298 299 299 299
    > 300 300 300 300 299 297 297 297 297 298 299 299 299
    > 300 300 300 300 299 297 297 297 297 298 299 299 299
    > 300 300 300 300 299 297 297 297 297 298 299 299 299
    >
    > 28000055 3
    > 300 300 300 300 301 301 301 300 301 301 301 301 300
    > 300 300 300 300 301 301 301 300 301 301 301 301 300
    > 300 300 300 300 301 301 301 300 301 301 301 301 300
    > 300 300 300 300 301 301 301 300 301 301 301 301 300
    >
    > Of the long lines, I want to read one line from each group, and ignore
    > everything else. I have relatively little experience with C++, and can
    > not find a suitable way to do this. Any suggestions? Please type a
    > small bit of sample code to show how suggested functions should be
    > used.
    >
    > Thanks! Andrew


    You have to find patterns that you can look for that identify where you are
    in your file. This means that you should read in each line and parse it. If
    I get you correctly then you want to read only one line of the blocks of 4
    lines, each containing 13 numbers. There are many ways you can do this. The
    basic idea is that you have to find the start and the end of the block. Thus
    you should be looking for things that definitely won't change. If every
    block has a header of two numbers you can look for a line containing only
    two numbers and read the next line. Go on reading until you reach the next
    line containing only two integers. Of course this works only under the
    assumption that there will always be a line with two numbers only before
    your block starts!

    The following code will show you one way to do it though it definitely is
    not the only or probably the best way. Nevertheless it should give you an
    idea and you should be able to come up with something yourself.

    #include <iostream>
    #include <fstream>
    #include <string>
    #include <vector>

    using namespace std;

    template< typename T>
    std::vector<T> MyStringToVector( const std::string& Str );

    int main()
    {
    ifstream In("c:\\myprojects\\test\\test.dat");
    vector<int> LineContents;
    string Line;

    if( !In ) {
    cerr << "Can't open input file" << endl;
    return false;
    }

    while( getline( In, Line ) ) {
    if( Line.find("<") == string::npos ) {
    LineContents = MyStringToVector<int>( Line );
    if( LineContents.size() <= 2 && LineContents.size() > 0 ) {
    getline( In, Line );
    cout << Line << endl;
    }
    }
    }

    return true;
    }
    ////////////////////////////////////////////////////////////////////////////
    //
    template< typename T>
    std::vector<T> MyStringToVector( const std::string& Str )
    // Tokenize a passed line/string into a vector
    // e.g:
    // std::string str = "1 2 3 4";
    // std::vector<int> vec = StringToVector<int>(str);
    ////////////////////////////////////////////////////////////////////////////
    //
    {
    std::istringstream iss( Str );
    std::vector<T> MyVec;
    std::copy( std::istream_iterator<T>(iss), std::istream_iterator<T>(),
    back_inserter( MyVec ) );
    return MyVec;
    }

    HTH
    Chris
     
    Chris Theis, Jul 29, 2003
    #3
    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. mtp
    Replies:
    4
    Views:
    845
  2. =?Utf-8?B?Sm9u?=

    Download a file with filename of mixed byte codes

    =?Utf-8?B?Sm9u?=, Aug 24, 2006, in forum: ASP .Net
    Replies:
    2
    Views:
    373
    =?Utf-8?B?Sm9u?=
    Aug 28, 2006
  3. Alex van der Spek

    Text file with mixed end-of-line terminations

    Alex van der Spek, Aug 31, 2011, in forum: Python
    Replies:
    2
    Views:
    200
    woooee
    Sep 1, 2011
  4. furby

    File uploading mixed with form input

    furby, Jul 11, 2006, in forum: ASP General
    Replies:
    3
    Views:
    176
    furby
    Jul 12, 2006
  5. Jaroslav Dobrek

    read from file with mixed encodings in Python3

    Jaroslav Dobrek, Nov 7, 2011, in forum: Python
    Replies:
    2
    Views:
    259
    Peter Otten
    Nov 7, 2011
Loading...

Share This Page