【问题标题】:[C++]Why Iterating over a std::string using std::stringstream gives an exception character?[C++]为什么使用 std::stringstream 对 std::string 进行迭代会产生异常字符?
【发布时间】:2021-11-07 03:11:32
【问题描述】:

我正在尝试实现一个简单的格式函数,根据给定的格式字符填充相应的内容。
我使用std::stringstream将给定的格式字符串转换为流,然后将字符一个一个取出。然后,根据单个字符,将相关内容填写到输出流中。 格式字符串以std::string 类型给出。

#include <iostream>
#include <sstream>
#include <string>

int main() {
    std::string fmt = "[%t]%Y-%M-%D<%H:%m:%s>:%c";
    std::stringstream s_res;
    std::stringstream s_fmt(fmt);
    while (s_fmt.good()) {
        char c = (char) s_fmt.get();
        if (c == '\0') break; // I'm not sure this stagement is necessary.
        if (c == '%') {
            switch (s_fmt.peek()) {
                case 't':
                    s_res << "Type";
                    break;
                case 'Y':
                    s_res << "Year";
                    break;
                case 'M':
                    s_res << "Month";
                    break;
                case 'D':
                    s_res << "Day";
                    break;
                case 'H':
                    s_res << "Hour";
                    break;
                case 'm':
                    s_res << "min";
                    break;
                case 's':
                    s_res << "sec";
                    break;
                case 'c':
                    s_res << "content";
                    break;
            }
            s_fmt.get();
            continue;
        }
        s_res << c;
    }
    std::cout << s_res.str();
    return 0;
}

正如预期的那样,程序应该输出如下内容:

Expected output: [Type]Year-Month-Day<Hour:min:sec>:content

但是在预期输出的最后,出现了一个奇怪的字符:

Actual Output:[Type]Year-Month-Day<Hour:min:sec>:content
========================================================^

查了很久,很苦恼,找不到可信的解释或具体的解决办法。

这是编码导致的问题吗?

我该如何解决这个问题?

【问题讨论】:

  • 输出语句应该是std::cout &lt;&lt; s_res.str() &lt;&lt; std::endl;(或'\n'而不是endl),如果最后一行没有以换行符结束会发生什么并没有明确定义

标签: c++ std stringstream


【解决方案1】:

假设流中的最后一个字符刚刚被处理。流中什么都没有了。

while (s_fmt.good()) {

这很好。毕竟,为什么不呢?到目前为止,一切都很顺利。已读取整个字符串。一切仍然是good()while 循环继续运行:

   char c = (char) s_fmt.get();

不幸的是,字符串的末尾已经到达。这失败了,when the end of the stream has been reached get() 返回

EOF 并设置 failbit 和 eofbit。

显示的代码不检查,并将返回的EOF 值盲目地转换为char。那是你的“奇怪的性格”。在while 循环的下一次迭代中,它会发现事情不再是good()(之前的get() 失败),然后退出。太晚了。

要解决这个问题,有必要从逻辑上重新安排事件的顺序。首先你get()下一个字符,然后你才能检查流是否是good(),否则就退出。或者,或者,检查明确的 EOF 返回值,您的偏好。

【讨论】:

    猜你喜欢
    • 2018-12-03
    • 2010-12-08
    • 2020-10-26
    • 1970-01-01
    • 2013-01-22
    • 1970-01-01
    • 2021-10-27
    • 1970-01-01
    • 2012-01-06
    相关资源
    最近更新 更多