I have a function named readNextString(ifstream &file , char* &pBuffer)
which extracts the next string from a file, until ','
or '\n'
is reached, removes whitespace at the beginning and at the end of the string, saves the rest in pBuffer and returns true if everything worked fine - false otherwise. Everything works until the end-of-file is reached. When the eof
flag is set I can't move my get pointer.
I've tried this:
if(file.eof())
{
file.clear();
file.seekg(0 , ios::end)
}
...and then remove whitespaces at the end of the string. This almost helped. The function extracts the string without the spaces but I get an infinite loop.
My actual question is: How can I check if the next char is EOF
, and if I can't - is there any alternative way to do this?
Here is my actual function:
bool readNextString(ifstream &file , char* &pBuffer)
{
if(file.eof()){
return false;
}
for(; file.good() && isWhitespace(file.peek()) && !file.eof() ; file.seekg(1 , ios::cur))
;
if(file.eof()){
cout << "The file is empty.\n";
return false;
}else{
streamoff startPos = file.tellg();
cout << "startPos : " << startPos << endl;
for(;file.good() && file.peek()!='\n' && file.peek()!=',' && file.peek()!= EOF; file.seekg(1 , ios::cur))
;
streamoff A = file.tellg();
cout << "A : " << A << endl;
file.seekg(-1 , ios::cur);
for(;file.good() && isWhitespace(file.peek()) ; file.seekg(-1 , ios::cur))
;
file.seekg(2 , ios::cur);
streamoff endPos = file.tellg();
cout << "endPos : " << endPos << endl;
pBuffer = new char[endPos-startPos];
if(pBuffer)
{
file.seekg(startPos , ios::beg);
file.get(pBuffer , endPos-startPos , ',' || '\n');
for(;file.good() && file.peek()!='\n' && file.peek()!=',' && file.peek()!= EOF; file.seekg(1 , ios::cur))
;
file.seekg(2 , ios::cur);
streamoff temp = file.tellg();
cout << "temp : " << temp << endl;
return true;
}else{
cout << "Error! Not enough memory to complete the task.\nPlease close some applications and try again.\n";
return false;
}
}
}
And that's one place where I call it:
void printCities()
{
ifstream city ;
city.open("cities.txt", fstream::in);
if(city.is_open())
{
char *currCity;
int counter = 1;
while(readNextString(city , currCity))
{
cout << counter++ << ". " << currCity << endl;
delete[] currCity;
currCity = NULL;
}
if(city.eof())
cout << "There are no cities added.\n";
city.close();
}else
cout << "Error by opening 'cities.txt'.Make sure that the file exist and try again.\n";
}
Hope I was clear enough. If you find some other mistakes or possible errors I'll be glad to hear it and learn from it.
Ok.I did it otherwise! getline() for the WIN ! :D So this is my code (this time is much more readable) :
bool readNextString(ifstream &file , char pBuffer[] )
{
while(isWhitespace(file.peek()) && !file.eof())
file.ignore(1);
if(!file.eof())
{
streamoff start = file.tellg();
stringstream toComma;
if(file.getline(pBuffer , 200 , ','))
{
toComma << pBuffer;
toComma.getline(pBuffer ,200, '\n');
int i=strlen(pBuffer)-1;
for(; isWhitespace(pBuffer[i]) ;i--)
;
pBuffer[i+1] = '\0';
file.clear();
file.seekg(start + strlen(pBuffer) , file.beg);
return true;
}else return false;
}
return false;
}
I've made some changes in my other function too:
void printCities()
{
ifstream city ;
city.open("cities.txt", fstream::in);
if(city.is_open())
{
if(!isEmpty(city))
{
char currCity[200];
int counter = 1;
while(readNextString(city , currCity) && counter < 10)
cout << counter++ << ". " << currCity << endl;
}else
cout << "There are no cities added.\n";
city.close();
}else
cout << "Error by opening 'cities.txt'.Make sure that the file exist and try again.\n";
}
The function isEmpty(ifstream &file)
returns true if the file is empty and false otherwise.
Thanks to all for help ! Best regards !