парсинг — c ++ чтение чисел из текстовых файлов, игнорирование комментариев

Так что я видел много решений на этом сайте и учебных пособий по чтению из текстового файла на C ++, но мне еще предстоит найти решение моей проблемы. Я новичок в C ++, поэтому я думаю, что у меня возникают проблемы с тем, чтобы собрать воедино часть документации, чтобы разобраться во всем этом.

То, что я пытаюсь сделать, это прочитать номера текстовых файлов, игнорируя при этом комментарии в файле, которые обозначены «#». Таким образом, файл примера будет выглядеть так:

#here is my comment
20 30 40 50
#this is my last comment
60 70 80 90

Мой код может хорошо читать цифры, когда нет комментариев, но я не понимаю, как анализировать поток достаточно хорошо, чтобы игнорировать комментарии. Это своего рода хакерское решение прямо сейчас.

/////////////////////// Read the file ///////////////////////
std::string line;
if (input_file.is_open())
{
//While we can still read the file
while (std::getline(input_file, line))
{
std::istringstream iss(line);
float num; // The number in the line

//while the iss is a number
while ((iss >> num))
{
//look at the number
}
}
}

else
{
std::cout << "Unable to open file";
}
/////////////////////// done reading file /////////////////

Есть ли способ, которым я могу включить обработку комментариев в это решение или мне нужен другой подход? Любой совет был бы отличным, спасибо.

0

Решение

Если ваш файл содержит # всегда в первом столбце, затем просто проверьте, начинается ли строка с # как это:

while (std::getline(input_file, line))
{
if (line[0] != "#" )
{
std::istringstream iss(line);
float num; // The number in the line

//while the iss is a number
while ((iss >> num))
{
//look at the number
}
}
}

Тем не менее, целесообразно обрезать линию начальных и конечных пробелов, как показано здесь, например: Удалить пробелы из std :: string в C ++

2

Другие решения

Если это только одно из применений, для линейно-ориентированного ввода, как у вас,
самое простое решение — просто убрать комментарий из строки, которую вы только что
читать:

line.erase( std::find( line.begin(), line.end(), '#' ), line.end() );

Более общим решением было бы использование фильтрующего потокового буфера, что-то
лайк:

class FilterCommentsStreambuf : public std::streambuf
{
std::istream& myOwner;
std::streambuf* mySource;
char myCommentChar;
char myBuffer;

protected:
int underflow()
{
int const eof = std::traits_type::eof();
int results = mySource->sbumpc();
if ( results == myCommentChar ) {
while ( results != eof && results != '\n') {
results = mySource->sbumpc(0;
}
}
if ( results != eof ) {
myBuffer = results;
setg( &myBuffer, &myBuffer, &myBuffer + 1 );
}
return results;
}

public:
FilterCommentsStreambuf( std::istream& source,
char comment = '#' )
: myOwner( source )
, mySource( source.rdbuf() )
, myCommentChar( comment )
{
myOwner.rdbuf( this );
}
~FilterCommentsStreambuf()
{
myOwner.rdbuf( mySource );
}
};

В этом случае вы могли бы даже отказаться getline:

FilterCommentsStreambuf filter( input_file );
double num;
while ( input_file >> num || !input_file.eof() ) {
if ( ! input_file ) {
//  Formatting error, output error message, clear the
//  error, and resynchronize the input---probably by
//  ignore'ing until end of line.
} else {
//  Do something with the number...
}
}

(В таких случаях я считаю полезным также отслеживать номер строки в
FilterCommentsStreambuf, Таким образом, у вас есть это за ошибку
Сообщения.)

2

Альтернативой «читать алине и анализировать его как строку» может быть использование самого потока в качестве входящего буфера:

while(input_file)
{
int n = 0;

char c;
input_file >> c; // will skip spaces ad read the first non-blank

if(c == '#')
{
while(c!='\n' && input_file) input_file.get(c);
continue; //may be not soooo beautiful, but does not introduce useless dynamic memory
}

//c is part of something else but comment, so give it back to parse it as number
input_file.unget(); //< this is what all the fuss is about!
if(input_file >> n)
{
// look at the nunber
continue;
}

// something else, but not an integer is there ....
// if you cannot recover the lopop will exit
}
0
По вопросам рекламы [email protected]