问题起源
在刷leetcode的时候,看到了discuss里面有一位大佬提出很有意思的解法。
这是一道mini parser的题,题目描述如下:
Given a nested list of integers represented as a string, implement a parser to deserialize it.
Each element is either an integer, or a list -- whose elements may also be integers or other lists.
Note: You may assume that the string is well-formed:
- String is non-empty.
- String does not contain white spaces.
- String contains only digits
0-9
,[
,-
,
, `]
他的解法是:
1 | /** |
关于istringstream
但是我今天要说的不是leetcode的解法,而是要介绍一种内存I/O——istringstream。
这个类的对象可以直接从string中读取数据,最基本的
istringstream是基于空格来提取字符串的,从而完成从字符串到其它类型的改变
基于空格提取字符串
1 |
|
从字符串转化成数字(int / double)
1 |
|
- 这里的i1为123,s1为“a”,s2为“,[456,[789]]]”;
- in能顺利将流输入到int类型的i1中,当遇到a时,流输入暂停;开始下一次的输入;
低层的I/O操作
首先引入几个流状态:
iostate value(member constant) | indicates | functions to check state flags | ||||
---|---|---|---|---|---|---|
good() | eof() | fail() | bad() | rdstate() | ||
goodbit | No errors (zero value iostate) | true |
false |
false |
false |
goodbit |
eofbit | End-of-File reached on input operation | false |
true |
false |
false |
eofbit |
failbit | Logical error on i/o operation | false |
false |
true |
false |
failbit |
badbit | Read/writing error on i/o operation | false |
false |
true |
true |
badbit |
引用自:http://www.cplusplus.com/reference/ios/ios/clear/
因此我们来修改一下啊刚才的例子:
1 |
|
- 此时,s1,i1都没有被输入正确的数,由于刚开始遇到了'a',流状态被设置为failbit;此时认为流已经结束;
为了避免这种情况发生,我们使用类内成员clear()去清除该状态,使得流状态处于goodbit;把注释去掉,我们可以看到s1变成了"a123a",也就是从错误的地方开始;
此时已经解决了部分的问题,但是如果我们仍然想要123这个整数怎么办?
此时引入了另外几个成员函数:get(),peek();
- is.get():将is的下一个字节作为int返回,并从流中删除它;
- is.peek():将is的下一个字节作为int返回,但不从流中删除它;
观察刚刚的例子,我们可以看到第一个字符为'a',因此我们可以从流中获取并删除它:
1 |
|
- 此时,输出m为字符'a'的ascii码97,i1为123,s1为“a";