这篇文章是一个简单的记录,解决类似这样的问题。
假设有一个字符串
1 | std::string = "<foo:bar> <baz:qux>"; |
要怎样才能读出其中的 foo:bar 以及 baz:qux 呢?使用 regex 正则库当然是一个办法,不过在规整的情况下,我们还有更优雅的选择。
std::getline
std::getline 函数来自头文件 string。因此,显而易见它是一个和字符串相关的函数。它有四个重载版本,具体如下:
1 | istream& getline (istream& is, string& str, char delim); |
其中第 2 个和第 4 个版本,分别是第 1 个和第 3 个版本对应的右值引用版本。函数基本的作用,是自输入流读入内容,直至遇见定界符(带 delim 的版本)或者换行符 \n(不带 delim 的版本),并将读入的内容写入字符串 str(不包括定界符本身)。
值得注意的是,函数会修改输入流 is 本身,并且返回它的左值引用。这一特性意味着 std::getline 函数可以「串行」执行。
实际解析看看
请看代码。
1 |
|
在这里,我们将 test 与字符串输入流 iss 绑定。
而后用 std::getline 从 iss 中先后将内容读入 skip 和 value。在这里,内层的 std::getline(iss, skip, LEFT_DELIM) 首先执行,将 LEFT_DELIM 之前的内容(实际上是空字符串)读入 skip 变量,而后修改 iss 的状态,并返回它的左值引用作为外层 std::getline 的第一个参数。而后,外层的 std::getline 将第一次遇到 RIGHT_DELIM 之前的内容 foo:bar 读入 value 变量。如此循环。
进入到外层 while 循环的内部,我们采用了类似的策略,分别将冒号前后的内容,存入 key 和 value 两个变量。读者可以自行分析。