Чтобы разделить комментарии и данные в файле .txt с помощью C++ fstream

У меня есть несколько файлов .txt со следующим шаблоном:

#Some comments here

bull rocket 3
trailer laker -12

#More comments there

Warriors Pacers 9

По сути, есть некоторые комментарии о том, что строки начинаются с #, а другие строки содержат две строки, за которыми следует int.

Мне нужны эти две строки и один int один за другим для обработки, и я должен игнорировать любую пустую строку или строку, начинающуюся с #

Я думаю использовать ifstream.get() для чтения первого символа и отбрасывания всей строки, если это #

Но я застрял, когда дело доходит до данных. Как я могу прочитать char, а затем получить первую строку? т. е. я нахожу «b», а затем мне нужен «бык». Что я должен делать?

Спасибо


person dunfa    schedule 26.02.2013    source источник


Ответы (5)


 #include <iostream>
 #include <fstream>
 #include <sstream>
 #include <string>
 using namespace std;
 int main()
 {
        fstream f1("f1.data");
        string line,w1,w2;
        int num;

        while ( getline(f1,line) ) {
                if ( istringstream(line) >> w1 >> w2 >> num
                  && w1[0] != '#' )
                        cout << w1 <<' '<< w2 <<' '<< num << '\n';
        }
 }

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

person jthill    schedule 26.02.2013
comment
np, я удалил ненужный файл temp. - person jthill; 26.02.2013

Используйте "while (std::getline(is, line)) {" для чтения файлового потока (std::istream is) построчно (std::string line) за раз.

Если line равно empty() или начинается с #, continue. Вы можете обрезать начальные пробелы перед выполнением этой проверки.

В противном случае проанализируйте строку (возможно, используя std::istringstream iss(line); iss >> first >> second >> value;). На StackOverflow есть много отличных примеров того, как это сделать.

person Johnsyweb    schedule 26.02.2013

Что-то в строках:

#include <iostream>
#include <string>
#include <fstream>
int main(){
  std::ifstream input("input");
  while (input.good()) {
    char c = input.peek();
    if (c == '#' || c == '\n') {
      input.ignore(256, '\n');
      continue;
    }   
    std::string s1, s2; 
    int i;
    input >> s1 >> s2 >> i;
    if (input.good())
      std::cout << s1 << " - " << s2 << " - " << i << std::endl;
  }
  input.close();
  return 0;
}
person perreal    schedule 26.02.2013

Образец кода:

    ifstream in("file.txt");
    if (!in.is_open())
        return false;

    string line;
    while (getline(in, line))
    {
        istringstream iss(line, istringstream::in);

        if (!line.length())
            continue;

        if (line[0] == '#') // Ignore the line starts with #
            continue;

       vector<string> words;

        string word;
        while (iss >> word)
        {
                words.push_back(word);
        }

        // now you have all words of current line
        // you can use them to parse your file
    }

Это пример кода, вы должны пропустить пробелы перед #. Например, полезна обрезка слева.

person masoud    schedule 26.02.2013
comment
Что такое вектор? - person e-info128; 24.12.2017

В качестве альтернативы ответу @MM. вы можете использовать новые возможности <regex> С++ 11. Однако обратите внимание, что в настоящее время не все стандартные библиотеки реализуют это полностью, поэтому вы также можете вернуться к Boost.regex при необходимости.

#include <fstream>
#include <iostream>
#include <sstream>

// note: Most C++11 regex implementations are not up to scratch, offer
// Boost.regex as an alternative.
#ifdef USE_BOOST_REGEX
#include <boost/regex.hpp>
namespace std
{
  using ::boost::regex;
  using ::boost::regex_match;
  using ::boost::smatch;
}
#else
#include <regex>
#endif

#include <string>
#include <tuple>
#include <vector>

int main()
{
  // open input file
  std::ifstream in("file.txt");
  if (!in.is_open()) return 1;
  // ECMAScript syntax!
  std::regex empty_or_comment_re("\\s*(?:#.*)?");
  // note: only matches integers
  std::regex values_re("\\s*(\\S+)\\s+(\\S+)\\s+(-?\\d+)\\s*");
  // will contain the results
  std::vector<std::tuple<std::string, std::string, int> > results;
  size_t lineno = 0; // for error reporting
  std::string line;
  // read lines
  while (getline(in, line))
  {
    ++lineno;
    // match empty or comment lines
    if (regex_match(line, empty_or_comment_re)) continue;
    // match lines containing data
    std::smatch match;
    if (!regex_match(line, match, values_re))
    {
      std::cerr<< "ERROR: malformed line in file.txt, line " << lineno
        << ".\n";
      return 1;
    }
    // read integer from match
    int n;
    std::istringstream iss(match[3]);
    iss >> n;
    // append to results
    results.push_back(std::make_tuple(match[1], match[2], n));
  }
}
person Michael Wild    schedule 26.02.2013