我正在尝试阅读一长篇文章,并将这篇文章分成包含的每个单词。我所做的第一次尝试是使用std::ifstreamoperator>>从文件中读取它以读取为字符串。问题是,由于它仅在空白字符上剪切文本,因此我仍然在短语的最后一个单词上得到句点(例如problem.)以及一些毫无意义的特殊字符串(有时我有->**)。

我曾想过按char读取char,或者也将字符串按char读取char拆分,然后发现删除了不在正确范围内的字符(az,AZ和0-9之间的某个字符),但是这种解决方案看起来很混乱。另外,由于我使用的是GCC 4.8.3,因此无法使用正则表达式,并且无法使用Boost。

有没有比第二个更好的解决方案,或者这是个好方法?好的,我的意思是相对容易实现并产生预期的结果(仅字母数字字符)。

最佳答案

您可以在流语言环境中安装自定义ctype:

#include <iostream>
#include <locale>
#include <sstream>

class WordCharacterClassification : public std::ctype<char>
{
    private:
    typedef std::ctype<char> Base;
    const mask* initialize_table(const Base&);

    public:
    typedef Base::mask mask;
    typedef Base::char_type char_type;

    public:
    WordCharacterClassification(const Base& source, std::size_t refs = 0)
    :   Base(initialize_table(source), false, refs)
    {}


    private:
    mask m_table[Base::table_size];
};

inline const typename WordCharacterClassification::mask*
WordCharacterClassification::initialize_table(const Base& source) {
    const mask* src = source.table();
    const mask* src_end = src + Base::table_size;
    const mask space
        = std::ctype_base::space
        | std::ctype_base::cntrl
        | std::ctype_base::digit
        | std::ctype_base::punct;

    mask* dst = m_table;
    for( ; src < src_end; ++dst, ++src) {
        *dst = *src;
        if(*src & space)
            *dst |= std::ctype_base::space;
    }
    return m_table;
}


int main() {
    std::istringstream in("This->is a delimiter-test4words");
    std::locale locale = in.getloc();

    WordCharacterClassification classification(
        std::use_facet<std::ctype<char>>(locale),
        // We hold a reference and do not transfer ownership:
        true);

    in.imbue(std::locale(locale, &classification));

    std::string word;
    std::cout << "Words:\n";
    while(in >> word) {
        std::cout << word << '\n';
    }
}

注意:静态表(不复制原始表)将简化它。

关于c++ - 逐字朗读长篇文章,无垃圾,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/24683076/

10-11 09:30