I am returning to C++ after a decade in java and this has held me up for two weeks now. I have seen many posts with getline issues and these have led me to add many "cout"s trying to find exactly what is wrong. I have found out about the bad, fail and eof bits but still have the same issue. getline doesn't populate the string or go into the while loop. Don't know if it matters but I am coding on a Win7 PC in netbeans and compiling/running on a rasberry pi (running raspbian (Debian I think)).
All I am trying to do is read a simple text file using getline! Should be basic ('scuse the pun :-)) I have tried creating the text file with both Unix and ASCII line endings (0x0A and 0x0D0A) - made no difference. I am running the program with the same userid that created the text file so no permissions issues.
Getline sets the fail bit (only...not eof) but perror reports "Success" and I get no data in "work".
Here is most of the class that causes the error - with many debugging annotations. "theFile" is just an fstream ('cos in the future version I might want to open it for output instead). But here, as you can see from the output, I am definitely opening the file with ios::in. The "issue" happens with the getline loop (which is never entered) in the getValue member function. I haven't included the constructor but it only sets a few flags to false. And the caller (MJAppl) just calls MJConfigFile::getValue( "log_dir", false ).
string MJConfigFile::getValue ( string in_key, bool in_restart ) {
bool found = false ;
string work , ret ;
int key_len = in_key.length() , loop_count = 0 ;
//char workbuf [ 200 ] ;
cout << "MJConfigFile::getValue entry for key " << in_key << " \n" ;
cout << "File name is " << getFName () << "\n" ;
if ( in_restart || !openForInput ) {
theFile . close () ;
open ( false ) ;
}
if ( theFile . is_open ()) {
cout << "File " << fullFileName << " is open." << "\n";
} else {
perror ( "Error while opening file " ) ;
}
while ( getline ( theFile, work )) {
if (loop_count++ > 5 ) return "Stopped \n" ;
cout << "Line '" << work << "'\n";
if ( in_key.compare ( work ) == 0 ) {
ret = work.substr ( key_len + 1 ) ;
break ;
}
}
perror ( "Error reading file. " ) ;
cout << "Line after loop '" << work << "'\n";
if ( theFile.bad() | theFile.fail() | theFile.eof()) {
if ( theFile . bad () ) cout << "Bad file." << endl ;
if ( theFile . fail() ) cout << "Fail file." << endl ;
if ( theFile . eof () ) cout << "eof file." << endl ;
}
return ret ;
}
void MJConfigFile::open () {
this -> open ( false ) ;
}
void MJConfigFile::open ( bool in_for_output ) {
if ( in_for_output ) {
theFile . open ( fullFileName.c_str (), ios::out ) ;
if ( theFile . is_open ()) {
openForOutput = true ;
cout << "File is open for output. \n" ;
}
} else {
theFile . open ( fullFileName.c_str (), ios::in ) ;
if ( theFile . is_open ()) {
openForInput = true ;
cout << "File is open for input. \n" ;
}
}
if ( openForInput || openForOutput ) {
exists = true ;
}
}
Here is sample output from a run:
In default MJConfigFile constructor
File is open for input.
MJAppl.readConfigFile() entry.
File is open for input.
MJConfigFile::getValue entry for key log_dir
File name is /mjmaint/MJApplCfg/MJApplCfg.cfg
File /mjmaint/MJApplCfg/MJApplCfg.cfg is open.
Error reading file. : Success
Line after loop ''
Fail file.
logdir is
0
And here is a sample input file:
Aaaaaa
Bbbbbb
Cccccc
I am just about ready to give up and go back to java so any help would be REALLY appreciated.