我使用getline
从输入文件中获取缓冲区中的字符。在读取一行之后,我循环遍历所有字符并在映射上执行查找(用于一些进一步的操作)。问题是,一旦有效字符结束,我的程序从输入流中获取eof,并尝试在映射中查找它。
我试着检查inputStream.eof()
或eofbit
,看看当我到达流的末尾时,但问题是,一旦我完成最后的getline()
,这两者都会被设置,所以我不能用它来确定EOF字符位于输入缓冲区中的位置。
我如何在输入缓冲区中识别EOF字符,并避免在映射中查找它?
while(fileInput) {
fileInput.getline(charBuf,charBufSize);
for(int i=0; i<=charBufSize ;i++) {
char* currentChar = &(charBuf[i]);
// do something with currentChar,
// which I proceed to do by dereferencing currentChar when I need to access
// the actual character.
}
}
c++中没有可以检查的EOF字符。你要做的是得到一个字符的数目,并使用它来知道文件结束的地方。您可以使用istream::gcount()
获取此计数。
你的代码中有几个问题。
我假设你已经声明了
char charBuf[256];
size_t charBufSize = 256;
第一个问题是您丢弃了第一行输入。从文件中逐行读取的惯用用法是:
while( fileInput.getLine(charBuf, charBufSize) ) { for (...) { // your for loop is wrong, but I'll get to that in a second } }
如果您真的想在开始循环之前丢弃第一行,请使用
fileInput.getLine(charBuf, charBufSize); // this first line will be ignored while( fileInput.getLine(charBuf, charBufSize) ) { for (...) { // your for loop is wrong, but I'll get to that in a second } }
charBufSize包含可以读取的最大数据量,而不是实际读取的数据量。所以如果你只读入,比如说,12个字符,那么你不仅要在字符13上执行映射查找,还会尝试处理字符14到256。为了避免这种情况,将循环改为:
for (int i=0; i < fileInput.gcount(); ++i ) { char* currentChar = &(charBuf[i]); // do something with currentChar, // which I proceed to do by dereferencing currentChar when I need to access // the actual character. }
您正在使用
<=
而不是<
。整个
char* currentChar = &(charBuf[i]);
的事情有点不寻常。在代码中,我从你的问题中编辑了出来(这样你问的基本输入问题就会更清楚),似乎你正确地使用了它,但似乎你可以很容易地声明char currentChar = charBuf[i];
做了一些小的改变,以避免在你使用它的地方取消引用currentChar
。
在charBuf中没有"EOF字符"。即使在EOF字符作为一个概念存在的系统上(例如MS-DOS和Windows), istream::getline()也不会将其存储在charBuf.
所发布的代码中一个明显的错误是循环中的越界访问:i<=charBufSize
应该是i<charBufSize
,但是为了只处理由istream::getline获得的字符,您应该使用fileInput.gcount()
来找出实际写入charBuf:
// assuming char charBuf[charBufSize];
fileInput.getline(charBuf, charBufSize);
for(int i=0; i<fileInput.gcount()-1; i++) // -1 if you don't want to process ' '
{
或者直接使用字符串
// assuming std::string charBuf;
getline(fileInput, charBuf);
for(int i=0; i<charBuf.size(); i++)
{
如果您想逐行读取,那么使用标准的getline习惯用法:
std::string line;
while (std::getline(inputFile, line))
{
// process line
}
如果您想要读取未格式化的("二进制")输入,请使用read
和gcount
:
std::array<char, 4096> buf;
std::streamsize n;
while (true)
{
inputFile.read(buf.data(), buf.size());
if ((n = inputFile.gcount()) == 0) { break; }
// process [buf, buf + n)
}