Reading from a text file that also is binary

T

The Cool Giraffe

Regarding the following code i have a problem.

void read () {
fstream file;
ios::eek:pen_mode opMode = ios::in;
file.open ("some.txt", opMode);
char *ch = new char[1];
vector <char> v;
while (!file.eof ()) {
do {
file.read (ch, 1);
v.push_back (*ch);
}
while ((int)ch[0] != 10 || file.eof ());
}
file.close ();
}

For some reason, one that i don't comprehend, i get through
the inner while-loop three times (as suppsed to) but then, i
get stuck and the computer does not see the end of the file.

Contents of the file are three lines of normal text and then
a double saved binary.

Any thoughts? My guess is that it's perhaps due to that i
didn't open the file binary but does it really matter to
recognizing "the end"? How can i "switch" the openess
of the file?

Yes, the file _IS_ supposed to have a leading few lines of
normal text and then a bunch of binary data. Sad but true...
 
G

Gianni Mariani

The said:
Regarding the following code i have a problem.

void read () {
fstream file;
ios::eek:pen_mode opMode = ios::in;
file.open ("some.txt", opMode);

If you expect *ANY* binary data in the file you must open it in binary
mode. This means that you will get platform specific line endings which
means you need to parse them.

x '\n' x - is a unix newline
x '\r' '\n' x - is a windows newline
x '\r' x - I think (not sure) is a MAC newline.

Basically eat up at most one \n and \r and then send back a newline.
char *ch = new char[1];

char ch[1] not good enough ? Or just plain char ch ?
vector <char> v;
while (!file.eof ()) {
do {
file.read (ch, 1);
v.push_back (*ch);
}
while ((int)ch[0] != 10 || file.eof ());

Should that not be ! file.eof() ?
 
T

The Cool Giraffe

Gianni Mariani wrote/skrev/kaita/popisal/schreibt :
The Cool Giraffe wrote:

If you expect *ANY* binary data in the file you must open it in binary
mode. This means that you will get platform specific line endings
which means you need to parse them.

x '\n' x - is a unix newline
x '\r' '\n' x - is a windows newline
x '\r' x - I think (not sure) is a MAC newline.

I tried with '\n' on the WinXP i'm on and it worked too. Should i
thank the nice employers of mr. Gates for this feature or should
i duck preparing for further issues if i keep using '\n'?
Basically eat up at most one \n and \r and then send back a newline.
char *ch = new char[1];

char ch[1] not good enough ? Or just plain char ch ?
vector <char> v;
while (!file.eof ()) {
do {
file.read (ch, 1);
v.push_back (*ch);
}
while ((int)ch[0] != 10 || file.eof ());

Should that not be ! file.eof() ?

Actually, not quite. It took my a while but i finally realized that
not only the negation was needed (as you suggested) but also
conjunction, instead of disjunction.
 
J

James Kanze

Regarding the following code i have a problem.

I'm not sure what you're trying to do, but this is certainly
wrong. (In general, anytime you use istream::eof() in the
control of a loop, it's wrong.)
void read () {
fstream file;
ios::eek:pen_mode opMode = ios::in;
file.open ("some.txt", opMode);
char *ch = new char[1];
vector <char> v;
while (!file.eof ()) {
do {
file.read (ch, 1);
v.push_back (*ch);

Note that if you are at EOF, and the read fails, then you will
push back the previously read character.
}
while ((int)ch[0] != 10 || file.eof ());

You want to loop if you've seen EOF? (And what on earth is 10.)

What I suspect you want is something like:

char ch ;
while ( file.get( ch ) && ch != '\n' ) {
v.push_back( ch ) ;
}

This will read all of the characters up to the first '\n',
inserting them into the vector, and then leave the file
positionned after the '\n'.
}
file.close ();
}
For some reason, one that i don't comprehend, i get through
the inner while-loop three times (as suppsed to) but then, i
get stuck and the computer does not see the end of the file.

Once you reach end of file, the nested loop is infinite.
Contents of the file are three lines of normal text and then
a double saved binary.

Which means that you must open the file in binary, and that you
don't expect EOF when reading the three lines. I'd do something
like:

std::vector< std::string > lines ;
std::string thisLine ;
char ch ;
while ( lines.size() != 3 && file.get( ch ) ) {
if ( ch != 0x0D ) {
if ( ch == 0x0A ) {
lines.push_back( thisLine ) ;
thisLine.clear() ;
} else {
thisLine += ch ;
}
}
}

This will handle the end of line conventions under both Unix and
Windows correctly (but not necessarily under other systems),
reading three lines, and leaving the file positionned after the
end of line of the last line.
Any thoughts? My guess is that it's perhaps due to that i
didn't open the file binary but does it really matter to
recognizing "the end"?

It can. Opening it in text would greatly simplify the above,
but would mean that you cannot possibly read the double
correctly.
How can i "switch" the openess
of the file?

You mean the mode: you can't, once the file is open.
Yes, the file _IS_ supposed to have a leading few lines of
normal text and then a bunch of binary data. Sad but true...

I've run into a similar convention before. In such cases,
you're stuck with reading it in binary, and recognizing the line
endings yourself.
 

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,770
Messages
2,569,584
Members
45,075
Latest member
MakersCBDBloodSupport

Latest Threads

Top