Я пытаюсь создать код 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, будет напечатано «Это правда!» количество строк в моем входном файле
Что я делаю неправильно?
Спасибо!!
Я могу только предположить, что:
Так что либо
Лучше всего: использовать «правильный» парсер для выполнения работы.
Обновить добавив быстрый & грязный подход с использованием 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";
}
Вам вообще не нужна библиотека типа 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
}
}
}