我正在尝试阅读一篇长篇文章,并将此文本分成它包含的每个单词。我做的第一次尝试是使用std::ifstream
和operator>>
从文件中读取它以读取字符串。问题是,因为它只剪切空白字符上的文本,我仍然会在短语的最后一个单词(如problem.
)和一些特殊字符串中得到句点(有时我没有->
}或**
)。
我想通过char读取char,或者也可以通过char拆分字符串read char,并找到不正确范围内的字符(az,AZ和0-9之间的字符),但这个解决方案似乎非常混乱。此外,我无法使用正则表达式,因为我使用GCC 4.8.3并且无法使用Boost。
有没有比第二个更好的解决方案,还是这是好方法?好的,我的意思是相对容易实现并产生预期的结果(只有字母数字字符)。
答案 0 :(得分: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';
}
}
注意:静态表(不复制原件)会简化它。
答案 1 :(得分:0)
您的第二个解决方案将是一个实现,可能会帮助您学习如何处理输入。您可以根据isalpha(http://www.cplusplus.com/reference/cctype/isalpha/)处理每个字符。任何返回false的内容都会立即结束“当前单词”并从下一个单词开始。