0

这是我写的代码......非常基本,因为我是初学者......

源文件如下所示:

Integers:
1 2 3 4 56 ...

String:
This is a string......
...(text).....

代码应该根据它在开头遇到的关键字来读取文本,,,

#include <iostream>
#include <fstream>
#include <string>
using namespace std;

int main ()
{
    int i;
    string STRING;
    char *inname = "source.txt";
    ifstream infile(inname);

    if (!infile) 
    {
        cout << "There was a problem opening file "<< inname<< " for reading."<< endl;
        return 0;
    };
    while (STRING != "Integer:")
        {
            getline(infile,STRING); // Saves the line in STRING.

            cout<<STRING<<endl; // Prints our STRING.
        };

    };
    cout << "Opened " << inname << " for reading." << endl<<endl<<"Integers:";
    while (infile >> i) {
        cout<<endl<<i<<endl;
    infile.close();
    return 0;
    }
}

非常感谢!

4

2 回答 2

0

IMHO you are missing some state in your parser, some check if the file is still valid and parsing the integers.

Here is a proof of concept:

#include <fstream>
#include <iostream>
#include <vector>

namespace {

  void parse_integers(std::vector<int> & vi, std::string const & line) {
    // Using strtol here - other tokenizers are possible.
    char const * ip { line.c_str() };
    char * ep;

    do {
      long int const v { strtol( ip, &ep, 10 ) };
      vi.push_back( v );
      ip = ep;
    } while( *ep != '\0' );

  }
}

int main() {

  std::string   inname { "source.txt" };
  std::ifstream infile { inname };

  if( ! infile ) {
    std::cout << "There was a problem opening file "
          << inname << " for reading." << std::endl;
        return 0;
  };

  enum class ParseState {
    outer, found_integers, found_string
  };

  ParseState ps { ParseState::outer };

  std::vector<int> s_integers;
  std::string      s_string;

  while( infile ) {
    std::string line;
    getline( infile, line );

    // Skip empty lines
    if( line.size() == 0 ) {
      continue;
    }

    if( line == "Integers:" ) {
      ps = ParseState::found_integers;
      continue;
    } else if( line == "String:" ) {
      ps = ParseState::found_string;
      continue;
    }

    // Hope that a section was already found....
    if( ps == ParseState::outer ) {
      std::cerr << "Line with data but without a section found ["
        << line << "]" << std::endl;
      continue;
    }

    switch( ps ) {
    case ParseState::found_integers:
      parse_integers(s_integers, line);
      break;

    case ParseState::found_string:
      s_string += line + "\n";
      break;

    case ParseState::outer:
      // Cannot happen
      abort();
    }
  }

  std::cout << "Dump file contents" << std::endl;
  std::cout << "Strings: [" << s_string << "]" << std::endl;
  std::cout << "Integers: ";
  for(int i : s_integers) {
    std::cout << "[" << i << "] ";
  }
  std::cout << std::endl;

  return 0;
}

Input:

Integers:
1 2 3 4 56 111 761 777

String:
This is a string......
...(text).....

Output:

Dump file contents
Strings: [This is a string......
...(text).....
]
Integers: [1] [2] [3] [4] [56] [111] [761] [777] 
于 2013-01-21T07:21:35.283 回答
0

您需要标记在该行中找到的单词。有很多方法可以做到这一点,您可以使用stringstreamboost tokenizer,甚至编写自己的代码。

假设您创建了一个规则,其中每个单词(标记)由空格分隔,并且您已经设法标记了这些行,那么您可以编写一个代码检查该行中的第一个标记并适当地采取行动

于 2013-01-21T04:12:56.757 回答