getline 函数的多个分隔符,C++

Eli*_*doo 4 c++ io

我想逐字阅读文本,以简单的方式避免任何非字母数字字符。在从带有空格和 '\n' 的文本“进化”之后,我需要解决这个问题,以防还有 ',', '.' 例如。第一种情况是通过使用带有分隔符“ ”的 getline 来解决的。我想知道是否有一种方法可以使用getline多个分隔符,甚至某种正则表达式(例如 '.'|' '|','|'\n')。

据我所知,它的getline工作方式是从输入流中读取字符,直到delimiter到达'\n' 或字符为止。我的第一个猜测是为它提供多个分隔符非常简单,但我发现事实并非如此。

编辑:作为澄清。任何 C 风格(例如 strtok,在我看来非常丑陋)或算法类型的解决方案都不是我想要的。想出一个简单的算法来解决这个问题并实现它是相当容易的。我正在寻找一个更优雅的解决方案,或者至少解释为什么我们不能用getline函数来处理它,因为除非我完全误解了,否则应该能够以某种方式接受多个分隔符。

Jer*_*fin 6

有好消息和坏消息。好消息是你可以做到这一点。

坏消息是这样做相当迂回,有些人发现它非常丑陋和讨厌。

为此,您首先要观察两个事实:

  1. 普通的字符串提取器使用空格来分隔“单词”。
  2. 什么构成空白是在流的语言环境中定义的。

将它们放在一起,答案就变得相当明显(如果是迂回的):要定义多个分隔符,我们定义一个区域设置,允许我们指定哪些字符应该被视为分隔符(即空格):

struct word_reader : std::ctype<char> {
    word_reader(std::string const &delims) : std::ctype<char>(get_table(delims)) {}
    static std::ctype_base::mask const* get_table(std::string const &delims) {
        static std::vector<std::ctype_base::mask> rc(table_size, std::ctype_base::mask());

        for (char ch : delims)
            rc[ch] = std::ctype_base::space;
        return &rc[0];
    }
};
Run Code Online (Sandbox Code Playgroud)

然后我们需要告诉流使用该语言环境(好吧,一个具有该 ctype 方面的语言环境),传递我们想要用作分隔符的字符,然后从流中提取单词:

int main() {
    std::istringstream in("word1, word2. word3,word4");

    // create a ctype facet specifying delimiters, and tell stream to use it:
    in.imbue(std::locale(std::locale(), new word_reader(" ,.\n")));
    std::string word;

    // read words from the stream. Note we just use `>>`, not `std::getline`:
    while (in >> word)
        std::cout << word << "\n";
}
Run Code Online (Sandbox Code Playgroud)

结果就是(我希望)你想要的:提取没有标点符号的每个单词是“空白”。

word1
word2
word3
word4
Run Code Online (Sandbox Code Playgroud)

  • @VaradMahashabde:它只影响该流的区域设置,并且使用默认构造的区域设置,仅替换“ctype”方面。因此,它只影响该流对字符进行分类的方式。 (2认同)