如何初始化指向输出缓冲区长度的指针?

时间:2015-11-29 10:41:27

标签: c++ c pointers pcre

我使用pcre2库使用此代码进行正则表达式替换:

PCRE2_SIZE outlengthptr=256;                       //this line
PCRE2_UCHAR* output_buffer;                        //this line
output_buffer=(PCRE2_UCHAR*)malloc(outlengthptr);  //this line
uint32_t rplopts=PCRE2_SUBSTITUTE_GLOBAL;
int ret=pcre2_substitute(
  re1234,                    /*Points to the compiled pattern*/
  subject,               /*Points to the subject string*/
  subject_length,        /*Length of the subject string*/
  0,                     /*Offset in the subject at which to start matching*/
  rplopts,               /*Option bits*/
  0,                     /*Points to a match data block, or is NULL*/
  0,                     /*Points to a match context, or is NULL*/
  replace,               /*Points to the replacement string*/
  replace_length,        /*Length of the replacement string*/
  output_buffer,         /*Points to the output buffer*/
  &outlengthptr          /*Points to the length of the output buffer*/
);

但我似乎无法正确定义output_buffer和指向它的长度(outlengthptr)的指针。

当我给outlengthptr一个固定值时代码有效,但它仍然是固定的,即它不会更改为output_buffer的新长度。但根据pcre2_substitue() specification,它应该被更改为output_buffer的新内容:

  

length,startoffset和rlength值是代码单元,而不是字符,outlengthptr指向的变量的内容也是如此,它被更新为新字符串的实际长度。

问题是:

  1. 当我将outlengthptr设为固定值时,最终字符串会以固定长度截断。
  2. 如果我没有初始化变量outlengthptr,我会遇到分段错误。
  3. 这是该功能的原型:

     int pcre2_substitute(const pcre2_code *code, PCRE2_SPTR subject, PCRE2_SIZE length, PCRE2_SIZE startoffset, uint32_t options, pcre2_match_data *match_data, pcre2_match_context *mcontext, PCRE2_SPTR replacement, PCRE2_SIZE rlength, PCRE2_UCHAR *outputbuffer, PCRE2_SIZE *outlengthptr); 
    

    This is the man page of the function

1 个答案:

答案 0 :(得分:3)

pcre2api page表示以下内容(强调我的):

  

该函数返回已进行的替换次数。如果未找到匹配项,则此值可能为零,并且除非设置PCRE2_SUBSTITUTE_GLOBAL,否则永远不会大于1。如果发生错误,则返回负错误代码。除PCRE2_ERROR_NOMATCH(永不返回)之外,pcre2_match()或子串复制函数的任何错误都会直接传回。对于无效的替换字符串(美元符号后面的无法识别的序列)返回PCRE2_ERROR_BADREPLACEMENT,如果输出缓冲区不够大,则返回PCRE2_ERROR_NOMEMORY

首先从一个初始缓冲区开始,它应该能够容纳大部分结果 - 不是太大而不是太小。这取决于您的申请 例如,您可以尝试以输入字符串的120%长度作为启发式,因为对于大多数常见的正则表达式替换用法而言,这似乎是合理的选择。

然后,使用此缓冲区调用该函数,并将其传递给它。

  • 如果你得到肯定的结果(或零),你就完成了。
  • 如果获得PCRE2_ERROR_NOMEMORY,则将缓冲区大小加倍并重试(根据需要重复此步骤)
  • 如果您获得了不同的错误代码,请将其作为真正的错误案例进行处理。