我有一个名为readNextString(ifstream &file , char* &pBuffer)
的函数,它从文件中提取下一个字符串,直到达到','
或'\n'
,删除字符串开头和结尾的空格,将其余部分保存在pBuffer中,如果一切正常则返回true - 否则返回false。一切都有效,直到达到文件结尾。设置eof
标志后,我无法移动我的get指针。
我试过这个:
if(file.eof())
{
file.clear();
file.seekg(0 , ios::end)
}
...然后删除字符串末尾的空格。这几乎有帮助。该函数提取没有空格的字符串,但我得到一个无限循环。
我的实际问题是:我如何检查下一个字符是EOF
,如果我不能 - 是否有其他方法可以做到这一点?
这是我的实际功能:
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;
}
}
}
这就是我称之为的地方:
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";
}
希望我足够清楚。如果您发现其他一些错误或可能的错误,我会很高兴听到并从中学习。
答案 0 :(得分:3)
如何检查下一个字符是否为EOF?
喜欢这个
if (file.peek() == EOF)
{
// next char is EOF
...
}
答案 1 :(得分:1)
首先,不使用seek跳过空格。得到的 性格并完成它。
其次,你似乎误解了其含义
istream::good()
和istream::eof()
。 从不
istream::good()
适当的任何时候,和
输入后istream::eof()
通常只适用于
失败。至于你的循环跳过白色空间,通常
解决方案是:
while ( isspace( file.peek() ) && file.peek() != EOF ) {
file.get(); // ignore read character...
}
类似的评论也适用于其他循环,除了
你不会想忽略读取的字符。去收集
字符直到下一个','
,例如:
std::string field;
while ( file.peek() != ',' && file.peek() != EOF ) {
field.push_back( file.get() );
}
(和你的file.get( pBuffer, endPos - startPos, ',' || '\n' )
当然不会做你所期望的;表达式','
|| '\n'
将始终评估为true
,转换后
到char
,是'\01
。)
最后,虽然上述策略可行,但它更为可取
将更大的文本单元输入std::stream
并进行解析
那。如果文本是面向行的,请使用类似:
std::string line;
while ( std::getline( file, line ) ) {
// Parse line, using std::istringstream if appropriate,
// although this doesn't seem to be the case for your code.
}
这比你正在做的要简单几个数量级。
答案 2 :(得分:0)
好的。我做到了! getline()为WIN! :d 所以这是我的代码(这次更具可读性):
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;
}
我的其他功能也做了一些改变:
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";
}
如果文件为空,函数isEmpty(ifstream &file)
返回true,否则返回false。
感谢所有人的帮助! 最好的问候!