逐字逐句地阅读长文本,不要读垃圾

Read long text word by word without trash

本文关键字:文本 逐字逐句      更新时间:2023-10-16

我正试图阅读一个长文本,我把这个文本分成它包含的每个单词。我做的第一次尝试是从一个文件中读取它,使用std::ifstreamoperator>>读取到一个字符串。问题是,因为它只在空白字符上剪切文本,我仍然在短语的最后一个单词(如problem.)和一些不意味着什么的特殊字符串(有时我有->**)处获得句号。

我想读一个字符一个字符,或者分割字符串读一个字符一个字符,并找到删除不在正确范围内的字符(介于a-z, a-z和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';
    }
}

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

您的第二个解决方案将是一个实现,可能会帮助您学习如何处理输入。您可以根据isalpha (http://www.cplusplus.com/reference/cctype/isalpha/)处理每个字符。其中任何返回false的内容都将立即结束"当前单词"并从下一个单词开始