471,570 Members | 966 Online
Bytes | Software Development & Data Engineering Community
Post +

Home Posts Topics Members FAQ

Join Bytes to post your question to a community of 471,570 software developers and data experts.

reading a mixed file

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
Jul 19 '05 #1
2 5078
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.)

Jul 19 '05 #2

"adpsimpson" <a_***********@hotmail.com> wrote in message
news:51**************************@posting.google.c om...
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
Jul 19 '05 #3

This discussion thread is closed

Replies have been disabled for this discussion.

Similar topics

8 posts views Thread by Yeow | last post: by
3 posts views Thread by Sivaraj G via .NET 247 | last post: by
2 posts views Thread by Matt McGonigle | last post: by
4 posts views Thread by Ganesh Muthuvelu | last post: by
8 posts views Thread by Edward Diener | last post: by
10 posts views Thread by Tyler | last post: by
7 posts views Thread by =?Utf-8?B?SmltIFdhbHNo?= | last post: by
32 posts views Thread by Bill Cunningham | last post: by
reply views Thread by XIAOLAOHU | last post: by
reply views Thread by leo001 | last post: by
reply views Thread by Vinnie | last post: by
reply views Thread by lumer26 | last post: by
reply views Thread by lumer26 | last post: by

By using Bytes.com and it's services, you agree to our Privacy Policy and Terms of Use.

To disable or enable advertisements and analytics tracking please visit the manage ads & tracking page.