Reading a file.

S

szclark

Hello, I am trying to extract information from a file I have so that I
can answer some questions on it, the problem I'm having is that it is
returning back mostly gibberish and I really don't know what I can do
to change it into proper text. Thre is a section at the bottom of my
output that is in proper english but I don't know about the rest. The
file I am reading is a.HDR file and this is the code:

#include <fstream>
#include <iostream>
#include <string.h>

using namespace std;

void ReadFile()
{
ifstream fin("METSAT.HDR", ios::binary)
cout << "Contents of the file...\n";
char ch;
while(fin.get(ch))
cout << ch;
}

int main()
{
ReadFile();
return 0;
}

The output is all ASCII letters, so I was thinking of trying to find
out the ASCII values and changing them into their binary equivalent
which should help with some of the qestions I am needing to answer.

Any help would be greatly appreciated.

Stu.
 
J

Jim Langston

Hello, I am trying to extract information from a file I have so that I
can answer some questions on it, the problem I'm having is that it is
returning back mostly gibberish and I really don't know what I can do
to change it into proper text. Thre is a section at the bottom of my
output that is in proper english but I don't know about the rest. The
file I am reading is a.HDR file and this is the code:

#include <fstream>
#include <iostream>
#include <string.h>

using namespace std;

void ReadFile()
{
ifstream fin("METSAT.HDR", ios::binary)
cout << "Contents of the file...\n";
char ch;
while(fin.get(ch))
cout << ch;
}

int main()
{
ReadFile();
return 0;
}

The output is all ASCII letters, so I was thinking of trying to find
out the ASCII values and changing them into their binary equivalent
which should help with some of the qestions I am needing to answer.

Any help would be greatly appreciated.

One way to output their values is by casting them to an int.

cout << static_cast<int>( ch ) << " ";

you may want to show them as hex or not.

You might first want to download a hex editor, like hexedit, to look at the
values of the file directory. If you are on windows, you can download one
of the many versions of hexedit that will let you look at the contents of
the file. There is probably something equavalent in *nix.
 
J

James Kanze

One way to output their values is by casting them to an int.
cout << static_cast<int>( ch ) << " ";
you may want to show them as hex or not.

You might also want to cast them to unsigned char first (before
converting them to int).
You might first want to download a hex editor, like hexedit, to look at the
values of the file directory. If you are on windows, you can download one
of the many versions of hexedit that will let you look at the contents of
the file. There is probably something equavalent in *nix.

Both vim and emacs have modes for editing hex files. If all he
wants to do is look at it, however, the utility od should do the
trick. It's also available under Windows, at least with CygWin
or UWin (and probably with MSys).
 
S

szclark

You might also want to cast them to unsigned char first (before
converting them to int).


Both vim and emacs have modes for editing hex files. If all he
wants to do is look at it, however, the utility od should do the
trick. It's also available under Windows, at least with CygWin
or UWin (and probably with MSys).

--
James Kanze (GABI Software) email:[email protected]
Conseils en informatique orientée objet/
Beratung in objektorientierter Datenverarbeitung
9 place Sémard, 78210 St.-Cyr-l'École, France, +33 (0)1 30 23 00 34- Hide quoted text -

- Show quoted text -

Right, I have managed to read the file it's all ASCII characters, I've
realised that I need to read some stupid hand book to find out which
bytes need to be read or something... Anyway, is there a way I can
extract readable text from the file and write it to a text file? It
asks me to "Extract the administrative message contained within the
last 800 bytes of the Interpretation Block and write it to a disk file
called Admin.txt" I can see this piece of text when I compile the
program.
 
B

BobR

/* """ quote
Right, I have managed to read the file it's all ASCII characters, I've
realised that I need to read some stupid hand book to find out which
bytes need to be read or something... Anyway, is there a way I can
extract readable text from the file and write it to a text file? It
asks me to "Extract the administrative message contained within the
last 800 bytes of the Interpretation Block and write it to a disk file
called Admin.txt" I can see this piece of text when I compile the
program.
""" */

#include <iostream> // #include <ostream> // std::endl
#include <string>
#include <vector>

int main(){
std::vector<std::string> vFile;
std::ifstream in( "filename.txt" );
if( not in.is_open() ){
std::cerr<<" Open Failed! \n"; return EXIT_FAILURE;} // if(!in)
for( std::string line; std::getline( in, line ); /*m t*/ ){
vFile.push_back( line );
}
// now your whole file should be (no errors) in 'vFile'.
std::copy( vFile.begin(), vFile.end(),
std::eek:stream_iterator<std::string>( std::cout, "\n" ) );

// search the strings in the vector for the key.

// output whole file (make a copy)
std::eek:fstream out( "copyfilename.txt" );
if( not out.is_open() ){
std::cerr<<" Open Failed! \n"; return EXIT_FAILURE;} // if(!in)
std::copy( vFile.begin(), vFile.end(),
std::eek:stream_iterator<std::string>( out, "\n" ) );

return 0;
} // main()


If you only want the last 800 chars of the input file, try this:
{
std::ifstream in( "filename.txt" );
in.seekg( -800, std::ios::end ); // may need adjust for '\n'
std::eek:fstream out( "copyfilename.txt" );
for( std::string line; std::getline( in, line ); /*m t*/ ){
out<<line;
}
// ... or use one of the 'get' functions.
}
 
J

James Kanze

[...]
std::ifstream in( "filename.txt" );

The file is opened in text mode.
in.seekg( -800, std::ios::end ); // may need adjust for '\n'

So this is illegal.

The simplest way to do this is just to read the entire file into
a variable (std::string or std::vector< char >), then write it,
e.g.:

std::string s( (std::istreambuf_iterator< char >( in )),
(std::istreambuf_iterator< char >()) ) ;
std::copy( s.end() - std::min( s.size(), N ),
s.end(),
std::eek:streambuf_iterator< char >( out ) ) ;

This can quickly become very slow, however, or even fail, if the
file is large. (I regularly have to deal with log files of
hundreds of megabytes; I do *not* use this solution for them.)
The alternative is to open the file in binary mode, so you can
seek however you want in it.
 
S

szclark

Right, I have managed to read the file it's all ASCII characters, I've
realised that I need to read some stupid hand book to find out which
bytes need to be read or something... Anyway, is there a way I can
extract readable text from the file and write it to a text file? It
asks me to "Extract the administrative message contained within the
last 800 bytes of the Interpretation Block and write it to a disk file
called Admin.txt" I can see this piece of text when I compile the
program.
[...]

std::ifstream in( "filename.txt" );

The file is opened in text mode.
in.seekg( -800, std::ios::end ); // may need adjust for '\n'

So this is illegal.

The simplest way to do this is just to read the entire file into
a variable (std::string or std::vector< char >), then write it,
e.g.:

std::string s( (std::istreambuf_iterator< char >( in )),
(std::istreambuf_iterator< char >()) ) ;
std::copy( s.end() - std::min( s.size(), N ),
s.end(),
std::eek:streambuf_iterator< char >( out ) ) ;

This can quickly become very slow, however, or even fail, if the
file is large. (I regularly have to deal with log files of
hundreds of megabytes; I do *not* use this solution for them.)
The alternative is to open the file in binary mode, so you can
seek however you want in it.

--
James Kanze (GABI Software) email:[email protected]
Conseils en informatique orientée objet/
Beratung in objektorientierter Datenverarbeitung
9 place Sémard, 78210 St.-Cyr-l'École, France, +33 (0)1 30 23 00 34

Cheers guys, got what I needed :D

Stu
 
B

BobR

James Kanze wrote in message...
On Jul 16, 10:47 pm, "BobR" wrote:
/* """ quote
[...]
std::ifstream in( "filename.txt" );

The file is opened in text mode.
in.seekg( -800, std::ios::end ); // may need adjust for '\n'

So this is illegal.

""" */

I didn't test on the GNU side, but, window$ shows no difference:

{ // GCC(MinGW)3.3.1, win98se
using std::cout // for NG post
std::eek:fstream copout( "ZZtest.txt" );
// std::eek:fstream copout( "ZZtest.txt", // yes, this makes a difference!
// std::ios_base::eek:ut | std::ios_base::binary );
// .... but reads show identical results. needs offset adjust.

for( size_t i(0); i < 7; ++i ){
copout<<"Record "<<i<<std::endl;
}
copout.close();

std::ifstream copin( "ZZtest.txt" );
// if( not copin.is_open() ){/*....*/}
std::ifstream copinB( "ZZtest.txt",
std::ios_base::in | std::ios_base::binary );
// if( not copinB.is_open() ){/*....*/}

std::string line;
copin.clear(); // it's part of a bigger section of code, fail states.
copin.seekg( -20, std::ios::end ); // -18 if bin write
std::getline( copin, line );
cout<<" copin.seekg( -20, end )="<<line<<std::endl;

copinB.clear(); line = "";
copinB.seekg( -20, std::ios::end ); // -18 if bin write
std::getline( copinB, line );
cout<<" copinB.seekg( -20, end )="<<line<<std::endl;
}

// out(text): copin.seekg( -20, end )=Record 5
// out(bin): copinB.seekg( -20, end )=Record 5
// I get '4' (of 'Record 4') for both, if binary write & -20.

[ I also tried 'copin()-->copin.close()-->copinB()'(etc.), in case window$
was 'sync'-ing the files behind my back (as ms sometimes does things). <G>]

Do you get anything different? (OS, FS, compiler?)

I don't have access to as many different file-systems, compilers as you
obviously do, so, I tend to take your word as gospel. :-}
 
J

James Kanze

James Kanze wrote in message...
[...]

std::ifstream in( "filename.txt" );

The file is opened in text mode.
in.seekg( -800, std::ios::end ); // may need adjust for '\n'

So this is illegal.
I didn't test on the GNU side, but, window$ shows no difference:

I didn't test it anywhere. The standard says it's undefined
behavior, so the fact that it might happen to work with a few
compilers doesn't mean much. (In fact, it doesn't work
correctly under Windows, since you won't be positionned 800
char's from the end of the file, but some lesser amount. It
does work under Unix, because Unix makes no distinction between
text files and binary files.)

The correction is simple, of course. Just open the file in
binary mode.
{ // GCC(MinGW)3.3.1, win98se
using std::cout // for NG post
std::eek:fstream copout( "ZZtest.txt" );
// std::eek:fstream copout( "ZZtest.txt", // yes, this makes a difference!
// std::ios_base::eek:ut | std::ios_base::binary );
// .... but reads show identical results. needs offset adjust.
for( size_t i(0); i < 7; ++i ){
copout<<"Record "<<i<<std::endl;
}
copout.close();
std::ifstream copin( "ZZtest.txt" );
// if( not copin.is_open() ){/*....*/}
std::ifstream copinB( "ZZtest.txt",
std::ios_base::in | std::ios_base::binary );

Technically speaking, you can't read a file in binary mode if it
was written in text mode. (And I've actually seen machines
where it didn't work.)

But seeking will now work. But you apparently didn't read the
post you were replying to, since I said that the reason it
didn't work was because the file was opened in text mode. You
can seek pretty much where ever you want in binary mode.
 
B

BobR

Well, like I said, I'll take your word (and the standards) for it.
Thanks James.

Now if I can only *remember* this the next time! 'CRS' and 'sometimers'
don't make it easy. <G>
 

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,583
Members
45,074
Latest member
StanleyFra

Latest Threads

Top