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