【问题标题】:How do I properly parse a text file with multiple delimiters in C++?如何在 C++ 中正确解析具有多个分隔符的文本文件?
【发布时间】:2017-11-11 09:38:00
【问题描述】:

我必须将带有段落的输入文件解析为句子。输出中的每一行对应一个句子。基本上是对的,但我无法得到想要的结果。

我被要求使用的分隔符是:

  • .
  • 。”
  • ?
  • ?”

测试输入: 第一个故事是关于连接点的。

在最初的 6 个月后,我从里德学院退学了,但在我真正退学之前,我又留了 18 个月左右的时间。那我为什么退学了?

在我出生之前就开始了。我的生母是一个年轻的未婚大学研究生,她决定收养我。她非常强烈地认为我应该被大学毕业生收养,所以一切都准备好让我在出生时被律师和他的妻子收养。除了当我突然出现时,他们在最后一刻决定他们真的想要一个女孩。所以我的父母在等待名单上,半夜接到电话问:“我们有一个意想不到的男婴,你想要他吗?”他们说:“当然。”后来我的亲生母亲发现,我的母亲从未从大学毕业,而我的父亲从未从高中毕业。她拒绝签署最终的收养文件。几个月后,当我父母承诺我有一天会去上大学时,她才松了口气。

#include "FileIOs_WordPairs.h"
#include <fstream>
#include <sstream>
#include <vector>



using namespace std;
bool sentenceSplitter(string& fname, vector<string>& sentences)
{
    ifstream file;
    string temp;
    size_t pos = 0;

    string token;

    file.open(fname);
    if (file.fail())
    {
        cerr << "Failed to open the file" << endl;
        return(-1);
    }

    while (getline(file, temp))
    {
        istringstream iss(temp);

        while ((pos = temp.find_first_of(".")) != string::npos)
        {
            token = temp.substr(0, pos);
            if (token.length() != 0)
                cout << token << endl;
            temp = temp.substr(pos + strlen("."));
        }

        while ((pos = temp.find_first_of("?")) != string::npos)
        {
            token = temp.substr(0, pos);
            if (token.length() != 0)
                cout << token << endl;
            temp = temp.substr(pos + strlen("?"));
        }

        while ((pos = temp.find_first_of(".\"")) != string::npos)
        {
            token = temp.substr(0, pos);
            if (token.length() != 0)
                cout << token << endl;
            temp = temp.substr(pos + strlen(".\""));
        }

        while ((pos = temp.find_first_of("?\"")) != string::npos)
        {
            token = temp.substr(0, pos);
            if (token.length() != 0)
                cout << token << endl;
            temp = temp.substr(pos + strlen("?\""));
        }
    }

}

预期输出:

  • 第一个故事是关于连接点的
  • 在最初的 6 个月后,我从里德学院退学了,但在我真正退学之前,我又留了 18 个月左右的时间。
  • 那我为什么辍学
  • 在我出生之前就开始了
  • 我的生母是一名年轻的未婚大学研究生,她决定收养我
  • 她非常强烈地认为我应该被大学毕业生收养,所以一切都准备好让我在出生时被律师和他的妻子收养
  • 除了当我突然出现时,他们在最后一刻决定他们真的想要一个女孩
  • 所以我的父母在等待名单上,半夜接到电话问:“我们有一个意想不到的男婴;你想要他吗
  • 他们说:“当然
  • 我的亲生母亲后来发现我的母亲从未从大学毕业,而我的父亲从未从高中毕业
  • 她拒绝签署最终收养文件
  • 几个月后,当我父母承诺我有一天会去上大学时,她才松了口气

当前输出:

  • 第一个故事是关于连接点的
  • 在最初的 6 个月后,我从里德学院退学了,但在我真正退学之前,我又留了 18 个月左右的时间。
  • 那我为什么辍学
  • 在我出生之前就开始了
  • 我的生母是一名年轻的未婚大学研究生,她决定收养我
  • 她非常强烈地认为我应该被大学毕业生收养,所以一切都准备好让我在出生时被律师和他的妻子收养
  • 除了当我突然出现时,他们在最后一刻决定他们真的想要一个女孩
  • 所以我的父母在等待名单上,半夜接到电话问:“我们有一个意想不到的男婴;你想要他吗?”他们说:“当然
  • ”我的亲生母亲后来发现我妈大学没毕业,我爸高中也没毕业
  • 她拒绝签署最终收养文件
  • 几个月后,当我父母承诺我有一天会去上大学时,她才松了口气

简单地说,我找不到使用 ." 和 ?" 的方法作为分隔符

【问题讨论】:

  • 请记住,您的 while 循环按顺序完成,因此您可以找到并输出直到 .s 的所有文本 - 即使有 ?、." 或 @987654326 @ 它们之间。 Arash 建议使用 boost 是合理的,但您也可以逐个字符地迭代输入,将其复制到输出并决定何时注入 \ns。
  • 在这种情况下,最简单的可能是使用regular expression。

标签: c++ file parsing io delimiter


【解决方案1】:

使用boost库,很简单:

#include <iostream>
#include <string>
#include <boost/algorithm/string/regex.hpp>

int main()
{
    using namespace std;
    vector< string > results;
    std::string text = "Hi! How are you?? Today is a nice day.";
    boost::algorithm::split_regex( results, text, boost::regex( "\\!|\\.|\\?\\?" ) ) ;
    for(string sentence:results)
        std::cout << "[" << sentence << "]" << std::endl;
}

编译:

g++ -std=c++11 main.cpp -lboost_regex  && ./a.out

结果:

[Hi]
[ How are you]
[ Today is a nice day]
[]

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2015-03-09
    • 2023-03-30
    • 1970-01-01
    • 2023-03-31
    • 1970-01-01
    • 2012-05-05
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多