& Quot; ENDS_WITH & Quot; функция при чтении входного файла не работает

Я пытаюсь создать код C ++, который с помощью библиотек Boost читает входной файл, как показано ниже,

    1             12       13        0        0      1      0      INLE
.
.
.

В этом случае я должен выполнить действие, если условие, указанное в последнем столбце справа, является INLE.
У меня есть следующий код,

#include <iostream>
#include <fstream>
#include <string>
#include <boost/algorithm/string/predicate.hpp>int main(int argc, const char * argv[])
{
std::string line;
const std::string B_condition = "INLE";
std::ifstream myfile ("ramp.bnd");
if (myfile.is_open())
{
while ( getline (myfile,line) )
{
if (boost::algorithm::ends_with(line,B_condition)==true)
{
std::cout << "Its True! \n"; // just for testing
//add complete code
}
}
myfile.close();
}

else std::cout << "Unable to open file";

return 0;
}

при компиляции проблем нет, но при запуске ничего не показывает.

С другой стороны, если я изменю свое логическое условие на false, будет напечатано «Это правда!» количество строк в моем входном файле

Что я делаю неправильно?
Спасибо!!

1

Решение

Я могу только предположить, что:

  • Ваш файл содержит пробелы в конце (используйте обрезку)
  • Ваш файл имеет конец строки Windows (CRLF) но вы читаете его как текстовые файлы UNIX, то есть строки будут содержать завершающий `\ r ‘(CR) (часто отображается как ^ M в различных текстовых редакторах / пейджерах).

Так что либо

  • исправить окончания строки
  • вырезать пробелы из линий перед сравнением
  • или же и то и другое

Лучше всего: использовать «правильный» парсер для выполнения работы.

Обновить добавив быстрый & грязный подход с использованием Boost Spirit: посмотрите Жить на Колиру

int main()
{
std::ifstream myfile("ramp.bnd");
myfile.unsetf(std::ios::skipws);

boost::spirit::istream_iterator f(myfile), l;

using namespace qi;
bool ok = phrase_parse(f, l,
(repeat(7) [ int_ ] >> as_string[lexeme[+(char_ - eol)]])
[ phx::bind(process_line, _1, _2) ]
% eol, // supports CRLF and LF
blank);

if (!ok)
std::cerr << "Parse errors\n";
if (f!=l)
std::cerr << "Remaing input: '" << std::string(f,l) << "'\n";
}

Как вы можете видеть, он проверяет всю строку, предполагая (на данный момент), что столбцы имеют 7 целочисленных значений и строку (например, "INLE"). Теперь фактическая работа намного проще и может быть реализована в отдельной функции:

void process_line(std::vector<int> const& values, std::string const& kind)
{
if (kind == "INLE")
{
std::cout << "Column 1: " << values[0] << "\n";
}
}

Фактическая функция обработки не должна вмешиваться в обрезку, концы строк и даже анализ столбцов деталей 🙂

Полный код для справки

#include <iostream>
#include <fstream>
#include <boost/spirit/include/qi.hpp>
#include <boost/spirit/include/phoenix.hpp>

namespace qi  = boost::spirit::qi;
namespace phx = boost::phoenix;

static const std::string B_condition = "INLE";

void process_line(std::vector<int> const& values, std::string const& kind)
{
if (kind == "INLE")
{
std::cout << "Column 1: " << values[0] << "\n";
}
}

int main()
{
std::ifstream myfile("ramp.bnd");
myfile.unsetf(std::ios::skipws);

boost::spirit::istream_iterator f(myfile), l;

using namespace qi;
bool ok = phrase_parse(f, l,
(repeat(7) [ int_ ] >> as_string[lexeme[+(char_ - eol)]])
[ phx::bind(process_line, _1, _2) ]
% eol, // supports CRLF and LF
blank);

if (!ok)
std::cerr << "Parse errors\n";
if (f!=l)
std::cerr << "Remaing input: '" << std::string(f,l) << "'\n";
}
2

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

Вам вообще не нужна библиотека типа boost. Решение с чистым стандартом C ++ возможно и в некоторых строках кода:

const std::string B_condition = "INLE";
std::ifstream myfile ("ramp.bnd");

for( char c; myfile >> c; )
{
if( std::isdigit(c, myfile.getloc() ) ) // needs #include <locale>
{
int i;
if( myfile.putback(c) >> i )
std::cout << "read " << i << std::endl; // do something with 'i'
}
else
{
std::string token;
if( myfile.putback(c) >> token )
{
if( token == B_condition )
std::cout << B_condition << " found\n";
else
; // no number, no B_condition -> what ever You want to do
}
}
}
2