Отделение EOF от символьного буфера Getline - PullRequest
0 голосов
/ 26 декабря 2011

Я использую 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.
  }
}

Ответы [ 3 ]

2 голосов
/ 26 декабря 2011

В 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. Чтобы избежать этого, измените цикл на:

    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]); немного необычна.В коде, который я отредактировал из вашего вопроса (чтобы основной вводимый вопрос был более понятным), кажется, что вы используете его правильно, но кажется, что вы могли бы так же легко объявить char currentChar = charBuf[i];внесены незначительные изменения, чтобы избежать разыменования currentChar в одном месте, где вы его используете.

2 голосов
/ 26 декабря 2011

В charBuf нет "символа EOF".Даже в системах, где символ EOF существует в качестве концепции (например, MS-DOS и Windows), istream :: getline () не будет хранить его в charBuf. * ​​1001 *

Одна очевидная ошибка в опубликованном коде - выход из-ограниченный доступ в цикле: 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++)
{
0 голосов
/ 26 декабря 2011

Если вы хотите читать построчно, тогда используйте стандартную идиому 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)
}
...