strange issue with reading files...

BobR removeBadBobR at worldnet.att.net
Mon Jan 7 21:35:31 PST 2008



rory wrote in message...
>
> I've gone through both implementations cout'ing and message boxing
> everything and have found when if I open the binary file with the
> ios::ate mode and call tellg the get pointer positions are different
> in the two implementations. In my wx App it reports a larger position
> than in my standard c++ app. I also tried leaving out that mode and
> doing a seekg(0, ios::end), again both get pointer positions differ by
> the same amount, i.e., 1673. I tried to offset my seekg in the wx ap
> by 1673 to see if that would work but that didn't work either.
> Something else I checked was buf, it's is not returning null but it is
> not picking up the 10 digits at the end of the file.

Did you check numeric_limits to see if an 'int' can hold the number on your
system?
An 'int' can be 16 bits (ISO standards).

>  It seems to me
> that there is a problem with ifstream in my wx app. It is opening the
> file Ok but it is not reporting the correct file size. Here is my
> code, both for my c++ app and mw wx app. Sorry for the long post. I
> hope someone can spot what is going on, I'm stumped.
> Rory.
>
>
> standard c++ implementation:
>
>  csdText = "";
>   char buf[10];
>   ifstream inFile(argv[2], ios::binary);
>
>   if(!inFile)  cerr << "Error: Could not open data";
>   inFile.seekg(0, ios::end);
// >   cout << "File size:" << int(inFile.tellg()) << "\n";
    cout << "File size:" << long( inFile.tellg() ) << "\n";


>   inFile.seekg(-10, ios::end);
>   cout << "getP=" << int(inFile.tellg()) << "\n";
>   inFile.get(buf, sizeof(char)*10);
>
>   cout << buf << "\n";
>   int pos = atoi(buf)+10;
>   cout << pos << "\n";
>   inFile.seekg(-pos, ios::end);
>   cout << "getP=" << int(inFile.tellg()) << "\n";
>   csdText = "";
>   while(!inFile.eof()){
>         getline(inFile, str);
>         csdText = csdText+str;
>     }
> cout << csdText;
>
>
> wx implementation:
>
// >   std::string str = "";
// >   std::string csdText = "";

   std::string str;  // strings are default initialized
   std::string csdText;

>   wxString test;
>
>   char* buf = new char[10]; file://appName.c_str()

Better to use std::vector<char> (or one of the wxWidgets containers).
Your 'buf' is begging to be overflowed!!

>   ifstream inFile(appName.c_str(), ios::binary);
// >   if((inFile.rdstate() & ifstream::failbit)!=0)
     if( not inFile.is_open() ){
          std::cerr<<"\n ifstream FAILED"<<std::endl;
          }


>   wxMessageBox("Error seeking");
>   inFile.seekg(0, ios::end);
>   test.Printf("Position at end:%d", int(inFile.tellg()));
>   wxMessageBox(test);
>
>   inFile.seekg(-(10+1673), ios::end);
>   if((inFile.rdstate() & ifstream::badbit)!=0)
>   wxMessageBox("Error seeking");
>
>   test.Printf("Position after 1st seek:%d", int(inFile.tellg()));
>   wxMessageBox(test);
>
// >   inFile.get(buf, sizeof(char)*10);

     inFile.get( buf, 10 );  // sizeof(char) == 1

>   int pos = atoi(buf)+10+1673;
????
Try:
     int pos(0); // or: long pos(0);
     inFile >> pos;
     if( not pos ){ std::cerr << "No number (or zero) read!" <<std::endl;}

>   if(!buf)wxMessageBox("nothing");
????

>   else{
>   test.Printf("buf:%d", pos);
>   wxMessageBox(test);
>   }
>   inFile.seekg(-pos, ios::end);
>
>   test.Printf("Position after 2nd seek:%d", int(inFile.tellg()));
>   wxMessageBox(test);
>
>   csdText = "";                      file://3914575
>   while(!inFile.eof()){

Not good! Try:

     std::ifstream inFile( appName.c_str(),
                    std::ios_base::in | std::ios_base::binary );
// note: if you use 'binary', also use 'in'.

     for( std::string line; std::getline( inFile, line ); /*none*/ ){
          csdText += str;
          }// for(inFile)

If you must use 'while', do it this way:

   while( std::getline( inFile, str ) ){
        csdText += str;
        }
    if( inFile ){ std::cerr<<"File read failure!"<<std::endl; }
    // if it (getline) tried eof, the stream is in fail state.

.... otherwise you might read the last line twice, or ??.
"  [ from post on comp.lang.C++ ]
On Dec 13, 11:17 am, Richard Herring wrote:
> >> while ( ! input->eof() )
> It's also worth pointing out that this is almost never the
> right thing to do. eof() doesn't become true until *after* you
> have tried (and failed) to read beyond the end of the file.
[ J Kanze answer ]
Actually, whether it becomes true or not depends.  You can't
count on it one way or the other.
"

>         getline(inFile, str);
>         csdText = csdText+str;
>     }
>   wxMessageBox(csdText.c_str());

Are these numbers at the end of the file 'printable chars'?

     std::string Hi( "Hello \0 World" );
     std::cout<<Hi<<std::endl;
....will only print "Hello ".

Use std:: [ isprint, isdigit, etc. ] to check (see <cctype> for the list).

     if( std::isdigit( buf[0] ) ){
          // - do something -
          } // if(isdigit)

Are these numbers at the end of the file in an 'endian' format?
( How were they written to file? If you write out as binary long, and read
it back as chars, you won't get the same value!!  (little-endian) )

   long number(0);
   inFile >> number;
   std::ostringstream out;
   out<<number;
// ---
   std::string theNumber( out.str() );
   wxMessageBox( theNumber.c_str() );
// ---
or:
// ---
   wxMessageBox( out.str().c_str() );
// ---

Give my suggestions a try, and post back.
--
Bob R
POVrookie








More information about the wx-users mailing list