【问题标题】:Read long text word by word without trash逐字阅读长文本,不带垃圾
【发布时间】:2014-09-01 05:08:15
【问题描述】:

我正在尝试阅读一个长文本,并将该文本分成它包含的每个单词。我所做的第一次尝试是使用std::ifstreamoperator>> 从文件中读取它以读入字符串。问题是,因为它只剪切空白字符上的文本,我仍然会在短语的最后一个单词处得到句点(如problem.)和一些没有任何意义的特殊字符串(有时我有-> 或@987654325 @)。

我想逐个字符地读取字符,或者也将读取字符的字符串拆分成字符,并找到删除不在正确范围内的字符(介于 az、AZ 和 0-9 之间的字符),但这个解决方案似乎很乱。另外,由于我使用的是 GCC 4.8.3 并且无法使用 Boost,因此我无法使用正则表达式。

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

【问题讨论】:

    标签: c++ string file-io


    【解决方案1】:

    您可以在流语言环境中安装自定义 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';
        }
    }
    

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

    【讨论】:

      【解决方案2】:

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

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2018-09-07
        • 2019-05-23
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多