簡體   English   中英

如何在XS代碼中通過char處理字符串char

[英]How to process a string char by char in the XS code

我們假設有一段這樣的代碼:

  my $str = 'some text';
  my $result = my_subroutine($str);

my_subroutine()應該實現為Perl XS代碼。 例如,它可以返回(unicode)字符串的字節總和。

在XS代碼中,如何通過char處理字符串(a) char,作為一般方法,以及(b)逐字節處理,如果字符串由ASCII代碼子集組成(從本機轉換的內置函數) 字符串的數據結構為char [])?

在XS層,您將獲得字節或UTF-8字符串。 在一般情況下,您的代碼可能包含一個char *指向字符串中的下一個項目,隨着它的增加遞增。 有關在XS中使用的一組有用的UTF-8支持函數,請閱讀perlapi“Unicode支持”部分


我的一個例子來自http://cpansearch.perl.org/src/PEVANS/Tickit-0.15/lib/Tickit/Utils.xs

int textwidth(str)
    SV *str
  INIT:
    STRLEN len;
    const char *s, *e;

  CODE:
    RETVAL = 0;

    if(!SvUTF8(str)) {
      str = sv_mortalcopy(str);
      sv_utf8_upgrade(str);
    }

    s = SvPV_const(str, len);
    e = s + len;

    while(s < e) {
      UV ord = utf8n_to_uvchr(s, e-s, &len, (UTF8_DISALLOW_SURROGATE
                                               |UTF8_WARN_SURROGATE
                                               |UTF8_DISALLOW_FE_FF
                                               |UTF8_WARN_FE_FF
                                               |UTF8_WARN_NONCHAR));
      int width = wcwidth(ord);
      if(width == -1)
        XSRETURN_UNDEF;

      s += len;
      RETVAL += width;
    }

  OUTPUT:
    RETVAL

簡而言之,此函數一次迭代給定字符串一個Unicode字符,累積wcwidth()給出的寬度。

如果你期望字節:

STRLEN len;
char* buf = SvPVbyte(sv, len);

while (len--) {
   char byte = *(buf++);

   ... do something with byte ...
}

如果您期望文本或任何非字節字符:

STRLEN len;
U8* buf = SvPVutf8(sv, len);

while (len) {
   STRLEN ch_len;
   UV ch = utf8n_to_uvchr(buf, len, &ch_len, 0);
   buf += ch_len;
   len -= ch_len;

   ... do something with ch ...
}

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM