NEWLINE IN IOSTREAM

C

Chad E. Dollins

I've got some trick input that I need help reading.

I am using iostream because it is still a holiday weekend and I'm not
trying to stress, but I have some input that looks like this.

2

1453
2123
3342
4234
5123
6511
6123

1234
1234
2345
3456
3456
7432

Where the first number indicates a number of cases followed by an unknown
number of lines, for n case seperated be a empty line.

My question is how can I use iostream to tell the diffrence between a read
on an empty line and the other. I'm not sure that this makes sense,
because by default iostream ignores white space.

--Chad
 
M

Mike Wahler

Chad E. Dollins said:
I've got some trick input that I need help reading.

I am using iostream because it is still a holiday weekend and I'm not
trying to stress, but I have some input that looks like this.

2

1453
2123
3342
4234
5123
6511
6123

1234
1234
2345
3456
3456
7432

Where the first number indicates a number of cases followed by an unknown
number of lines, for n case seperated be a empty line.

My question is how can I use iostream to tell the diffrence between a read
on an empty line and the other. I'm not sure that this makes sense,
because by default iostream ignores white space.

It's not an istream object that ignores whitespace, but
the overloaded >> operator. You can read an entire line
at a time with the std::getline function (declared by <string>).

-Mike
 
M

Mike Wahler

Mike Wahler said:
It's not an istream object that ignores whitespace, but
the overloaded >> operator. You can read an entire line
at a time with the std::getline function (declared by <string>).

-Mike

#include <fstream>
#include <istream>
#include <iostream>
#include <sstream>
#include <string>

std::istream& parse(std::istream& in)
{
std::string line;
while(in)
{
while(in && line.empty())
{
std::getline(in, line);
}

std::istringstream iss(line);
unsigned int count(0);
iss >> count;

do
{
std::getline(in, line);
} while(in && line.empty());

std::cout << "count == " << count << '\n';

for(unsigned int i(0); i < count; ++i)
{
while(in && !line.empty())
{
std::cout << line << '\n';
std::getline(in, line);
}

std::cout << "[End of group " << i + 1 << "]\n";

while(in && line.empty())
std::getline(in, line);
}
}

if(in.eof())
std::cout << "<End of Input>\n";
else
std::cout << "** Error reading input**\n";

return in;
}

int main()
{
std::ifstream input("C:/test.txt");

if(input)
parse(input);

return 0;
}
/* ** (Not thoroughly tested ** */

Input:


2

1453
2123
3342
4234
5123
6511
6123

1234
1234
2345
3456
3456
7432



3



1453
2123
3342
4234
5123
6511
6123


1234
1234
2345
3456
3456
7432






1234
1234
2345
3456
3456
7432



Output:

count == 2
1453
2123
3342
4234
5123
6511
6123
[End of group 1]
1234
1234
2345
3456
3456
7432
[End of group 2]
count == 3
1453
2123
3342
4234
5123
6511
6123
[End of group 1]
1234
1234
2345
3456
3456
7432
[End of group 2]
1234
1234
2345
3456
3456
7432
[End of group 3]
<End of Input>

-Mike
 
D

Dietmar Kuehl

Chad said:
My question is how can I use iostream to tell the diffrence between a read
on an empty line and the other.

You simple need to process the whitespaces yourself rather than
leaving it to the formatted extractor. To do so, you need to
understand that formatted extractors begin processing by skipping
whitespaces. That is, after reading anything, the following
whitespaces are not touched and you can simple read them yourself.

Here is a possible approach how to do this conveniently:

#include <iostream>
#include <ctype.h>
#include <stdexcept>

struct nlcount { int count; nlcount(): count(0) {} };

std::istream& operator>> (std::istream& in, nlcount& nls)
{
std::istream::sentry kerberos(in, true);
if (kerberos)
{
std::streambuf* sbuf = in.rdbuf();
int eof = std::char_traits<char>::eof();
nls.count = 0;
int c = sbuf->sgetc();
for (; c != eof && std::isspace(c); c = sbuf->snextc())
if (c == std::char_traits<char>::to_int_type('\n'))
++nls.count;
if (c == eof)
in.setstate(std::ios_base::eofbit);
}
return in;
}

void read(std::istream& in)
{
int blocks = 0;
nlcount nls;
if (!(in >> blocks >> nls) || nls.count != 2)
throw std::runtime_error("missing newline after block count");

int value = 0;
for (int count = 1; count <= blocks && in; )
if (in >> value >> nls)
{
std::cout << count << ": " << value << "\n";
if (nls.count == 2)
++count;
}
}

int main()
{
try { read(std::cin); }
catch (std::exception const& ex) {
std::cerr << "ERROR: " << ex.what() << "\n";
}
}
 

Ask a Question

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

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

Forum statistics

Threads
473,769
Messages
2,569,580
Members
45,053
Latest member
BrodieSola

Latest Threads

Top