【问题标题】:Cannot parse string with null character无法解析带有空字符的字符串
【发布时间】:2014-10-16 22:14:58
【问题描述】:

我正在尝试为SCGI 请求编写解析器。我正在尝试解析示例中描述的字符串,但由于某种原因,我找不到第二个空字符的位置,即分隔内容长度值和下一个属性名称的位置。

这是我的测试字符串:

string scgi_request(
    "70:CONTENT_LENGTH\027\0SCGI\01\0REQUEST_METHOD\0POST\0REQUEST_URI\0" \
    "/deepthought\0,What is the answer to life?"
   , 91);

我可以找到第一个空字符的位置,位置 18。但是一旦我试图找到之后的那个,返回的位置是无效的,偏移了几个字符,一直到位置 24。

这是我的算法:

size_t contentLengthEnd = scgi_request.find('\0');
size_t contentLengthValueEnd = scgi_request.find('\0', ++contentLengthEnd);
std::cerr << contentLengthEnd << std::endl; // 19, because I shifted this one forward 
                                            // otherwise I'd always get the same 
                                            // character
std::cerr << contentLengthValueEnd << std::endl; // 24, no clu why.

【问题讨论】:

  • request 是什么?如果有的话,它与scgi_request 有什么关系?
  • @user657267 不应该这样,因为在ctor中他指定了字符串的长度,并且\0在构造上不被视为特殊字符
  • 我认为通过传递长度来创建字符串可以避免这种情况?
  • 抱歉,我现在才注意到添加了换行符。
  • 第一个\0 如您所述,位于第 18 位。下一个字符SCGI\01 占据位置 19-23。第二个\0 位于第 24 位。这不正确吗?

标签: c++ string c++11 scgi


【解决方案1】:

你的字符串开始:

"70:CONTENT_LENGTH\027\0SCGI\01\0REQUEST_METHOD\0POST\0REQUEST_URI\0" 

这些输出实际上对于您提供的字符串是正确的。我猜你可能忽略了\027 是一个八进制字符常量,等等。字符及其索引是:

16: 'H'
17: '\027'
18: '\0'
19: 'S'
20: 'C'
21: 'G'
22: 'I'
23: '\01'
24: '\0'
25: 'R'

您的程序会找到前两个'\0',它们是1824,但您在输出第一个之前执行++,因此输出1924

如果您的意思是 '\0' 然后是 '2' 然后是 '7' 那么您不需要并列这些东西,例如利用字符串文字连接:

"70:CONTENT_LENGTH\0"
"27\0" 
"SCGI\0"
"1\0"

【讨论】:

  • 如何找到数字 27?
  • @lapinrigolo 写入您的字符串不包含数字 27。'\027' 是不可打印的字符(无论如何都是 ASCII)。我已经更新了我的答案以提出修复建议
  • @lapinrigolo 您正在寻找特别的 ESC 字符?除了 '\0'! 之外,这需要额外的逻辑
  • @πάνταῥεῖ OP 中规范的链接表明 "\0" "27" 是有意的
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2022-09-27
  • 1970-01-01
  • 2020-05-01
  • 2023-04-10
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多