1

次のパターンの.txtファイルがいくつかあります。

#Some comments here

bull rocket 3
trailer laker -12

#More comments there

Warriors Pacers 9

基本的に、#で始まるコメントがいくつかあり、他の行には2つの文字列とそれに続くintが含まれています

処理するには、これら2つの文字列と1つのintが必要であり、空白行または#で始まる行を無視する必要があります。

ifstream.get()を使用して最初の文字を読み取り、それが#の場合は行全体を破棄することを考えています。

しかし、データに関しては行き詰まっています。文字を読み取って最初の文字列を取得するにはどうすればよいですか?つまり、「b」を見つけたら、「ブル」が必要です。私は何をすべきか?

ありがとう

4

5 に答える 5

3

「」を使用して、一度に1行()while (std::getline(is, line)) {のファイルストリーム()を読み取ります。std::istream isstd::string line

lineであるempty()か、で始まる場合#continue。このチェックを実行する前に、先頭の空白を削除することをお勧めします。

それ以外の場合は、行を解析します(おそらくを使用してstd::istringstream iss(line); iss >> first >> second >> value;)。このビットを実行する方法については、StackOverflowの他の場所に多くの優れた例があります。

于 2013-02-26T06:03:43.167 に答える
2

次の行の何か:

#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;
}
于 2013-02-26T06:41:58.827 に答える
2
 #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++の部分を最大限に活用してください。

于 2013-02-26T07:22:28.697 に答える
1

サンプルコード:

    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
    }

これはサンプルコードです。#の前の空白はスキップする必要があります。たとえば、左トリミングが便利です。

于 2013-02-26T06:05:35.507 に答える
0

@MM。の回答の代わりに<regex>、C ++ 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));
  }
}
于 2013-02-26T07:07:15.817 に答える