c++ - getline 函数的多个分隔符,c++

标签 c++ io

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

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

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

最佳答案

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

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

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

  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];
    }
};

然后我们需要告诉流使用该语言环境(嗯,具有该 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";
}

结果就是(我希望)你想要的:提取每个单词,而不使用我们所说的“空格”标点符号。

word1
word2
word3
word4

关于c++ - getline 函数的多个分隔符,c++,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/41028852/

相关文章:

c++ - glDrawElements() 在无效情况下返回 GL_INVALID_ENUM

c++ - C++ STL优先级队列使用什么堆结构?

java - Netty 乒乓球与 POJO

java - 两个与Java类似的复制代码,两种行为

c++ - std::regex——是否有一些需要链接的库?

c++ - 对于每个 "type"有一个带有构造函数重载的模板类是否合适

c++ - 使用 char** argv 时如何避免指针运算

perl - Perl 的 Capture::Tiny::capture() 是否避免了使用 system() 时所需的磁盘 io?

java - 永远不会结束的话题

java - 如何读取 BufferedReader 两次或多次?