将EOF与Getline的字符缓冲区分开

时间:2011-12-26 15:53:26

标签: c++ file-io eof

我正在使用getline从输入文件中获取缓冲区中的字符。读完一行后,我遍历所有字符并在地图上进行查找(进行一些进一步的操作)。 问题是,一旦有效字符结束,我的程序就从输入流中获取eof并尝试在地图中查找它。

我尝试检查inputStream.eof()eofbit,看看我何时到达流的末尾,但问题是这两个都是在我做出最终{{1}时设置的所以我不能用它来确定EOF字符在输入缓冲区中的位置。

如何在输入缓冲区中识别EOF字符并避免在地图中查找?

getline()

3 个答案:

答案 0 :(得分:2)

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 '\0'
{

或只使用字符串

// assuming std::string charBuf;
getline(fileInput, charBuf);
for(int i=0; i<charBuf.size(); i++)
{

答案 1 :(得分:2)

您可以检查C ++中没有EOF字符。您需要做的是获取读入的字符数,并使用它来知道文件的结束位置。您可以使用istream::gcount()来获取此计数。

您的代码中存在多个问题。

我假设您已宣布

char charBuf[256];
size_t charBufSize = 256;
  1. 第一个问题是您丢弃了第一行输入。从文件中逐行读取的通常习惯是:

    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
      }
    }
    
  2. charBufSize包含可读取的最大数据量,而不是实际读取的数据量。因此,如果您只读入12个字符,那么您不仅要在字符13上执行地图查找,而且还要尝试处理字符14到256.要避免这种情况,请将循环更改为:< / p>

    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.
    }
    
  3. 您使用<=代替<。我已在上面的代码示例中解决了这个问题。

  4. 整个char* currentChar = &(charBuf[i]);事情有点不寻常。在我从你的问题编辑出的代码中(这样你要问的基本输入问题会更清楚),看起来你正确使用它,但似乎你可以很容易地声明{{1进行了微小的更改,以避免在您使用它的地方取消引用char currentChar = charBuf[i];

答案 2 :(得分:0)

如果您想逐行阅读,请使用标准的getline习语:

std::string line;
while (std::getline(inputFile, line))
{
    // process line
}

如果您想要阅读未格式化(“二进制”)输入,请使用readgcount

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)
}