【问题标题】:Using an istringstream With ASCII 26 Character使用带有 ASCII 26 字符的 istringstream
【发布时间】:2021-03-02 04:49:59
【问题描述】:

我有一个相当简单的问题,但我无法在任何地方找到任何帮助,所以我希望得到一些帮助。我正在使用一些 C++ 字符串流,并且我的字符串数据导致我的流失败。具体来说,当我遇到 Ctrl-Z 字符(26 或 0x1A)时,流会失败,这并不奇怪。

首先,我有一个表示图像的数据字符串,从某种意义上说,字符串的每个字节(或字符)都表示某处图像的某个 RGB 值(确切的图像结构无关紧要)。从这个字符串中,我想重建它所代表的 RGB 值的图像。我采用的方法是将字符串转换为字符串流,以便更好地解析数据,因为开始字节包含我需要的标头信息。

看起来像这样:

std::string data = getImageData(); // Get the image from somewhere
std::istringstream ss(data);
char byte = ' ';
while (ss.get(byte)) {
   // PROCESS THE BYTE
}

这工作得很好,直到它不可避免地到达一些 ASCII 值为 26 的字节,这通常是一个 EOF 标记,并且流抛出它的标志并将其标记为失败。一旦发生这种情况,流将终止,我无法再从流中读取数据。我想知道如何绕过这个错误并继续阅读直到流为空。

我做了什么/研究了什么

字符串data 超出了我的控制范围。我无法更改它的内容,但理论上我可以在检索到它后更改它的值,因为它是原始图像数据的副本。一般来说,它应该是特定格式的图像数据,因此除了它的标题之外,字节值可以是任何东西,甚至是 ASCII 26。

我看到的许多建议都说用std::ios::binary 打开流,但这也不起作用。进一步的研究表明,字符串流不存在这种模式,但文件流确实存在。从理论上讲,如果数据来自文件流而不是字符串流,那么就不会有问题。不幸的是,数据必须以字符串形式出现,所以这超出了我的控制范围。从那里开始,我只是不知道是否有办法将字符串流读取为真正的二进制文件,而我就是想不通。

最大的问题是:有没有办法以二进制模式从字符串流中读取单个字节,这样 ASCII 字符 26 就不会引起问题,或者有没有更好的方法来管理字符串 data位置,这样这不是问题吗?

感谢您的阅读!

【问题讨论】:

  • 有趣的是,我无法重现您的问题,无论是在 Windows 上的 Visual Studio 还是在 Linux 上。你确定你的分析是正确的?我尝试将data 直接设置为字符串"abc\032def"(嵌入ascii 26)并且读取流不会在中间停止。难道data 已经在字符 26 处被截断了?或者循环体在那个字符上终止?无论如何,您似乎可以直接使用字符串,而不是通过流(如其中一个答案所建议的那样)。
  • @DanielJunglas 似乎直接使用字符串可能更可取。如果我错了,请纠正我; \0不是ASCII 0的空字符吗?我遇到了替换字符的问题。
  • @JoshB。 \032 是八进制 32 即十进制 26
  • @dxiv 哎呀!我的错。谢谢!

标签: c++ ascii istringstream


【解决方案1】:

我建议完全避免使用std::istringstream。由于您似乎一次只使用一个字符,因此只需遍历字符串并按照您认为合适的方式处理每个字符。

std::string data = getImageData();
for (char ch : data)
{
   // Use ch
}

【讨论】:

  • 或者如果存储是一个普通的旧字符数组,只需for (int i = 0; data[i]; i++) { ... }
  • 看起来使用普通字符串是可行的方法。那么出于好奇,由于我很天真,字符串流比普通字符串有什么优势?如果我们从网络或类似的东西中读取数据,它是否只是提供了一种更好的方法?因为从这里看来,解析字符串流似乎只会让我们头疼。
  • @JoshB。如果您希望收到一个包含您需要读取的数字的字符串,那么最好使用istringstream。您不想编写代码来解析应用程序中的传入字符串。让istringstream 为您处理。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2012-08-16
  • 2011-10-07
相关资源
最近更新 更多