9

質問が言うように:

typedef __CHAR16_TYPE__ char16_t; 

int main(void)
{
  static char16_t test[] = u"Hello World!\n";

  printf("Length = %d", strlen(test)); // strlen equivalent for char16_t ???

  return 0;
}

C++ソリューションのみを検索して見つけました。

私のコンパイラはGCC 4.7です。

編集:

code points明確にするために、私はのカウントではなく、のカウントを返すソリューションを探していましたcharacters

これら2つはUTF-16、の外の文字を含む文字列ではまったく異なりますBMP

4

5 に答える 5

5

これがあなたの基本的なstrlenです:

int strlen16(const char16_t* strarg)
{
   int count = 0;
   if(!strarg)
     return -1; //strarg is NULL pointer
   char16_t* str = strarg;
   while(*str)
   {
      count++;
      str++;
   }
   return count;
}

より効率的で人気のあるstrlenは次のとおりです。

int strlen16(const char16_t* strarg)
{
   if(!strarg)
     return -1; //strarg is NULL pointer
   char16_t* str = strarg;
   for(;*str;++str)
     ; // empty body
   return str-strarg;
}

お役に立てれば。

警告: UTF-16文字列の文字(コードポイントではない)をカウントする場合、これは正しく機能しません。__STDC_UTF_16__これは、がに定義されている場合に特に当てはまります1

UTF-16は可変長(BMP内の1文字あたり2バイト、またはBMP外の1文字あたり4バイト)であり、これらの関数の対象外です。

于 2013-01-25T19:10:35.117 に答える
5

std::char_traitsにはこれがあります。

#include <string>

std::char_traits<char16_t>::length(yourchar16pointerhere);
于 2018-04-06T01:04:12.103 に答える
3
#include <string.h>
#include <wchar.h>
#include <uchar.h>

#define char8_t char
#define strlen8 strlen
#define strlen16 strlen16
#define strlen32(s) wcslen((const wchar_t*)s)

static inline size_t strlen16(register const char16_t * string) {
    if (!string) return 0;
    register size_t len = 0;
    while(string[len++]);
    return len;
}

char16_tバイト数ではなく、返される文字数を期待する必要があります。

最適化された32ビットIntelAtomアセンブリビュー:

gcc -Wpedantic -std=iso9899:2011 -g3 -O2 -MMD -faggressive-loop-optimizations -fkeep-inline-functions -march=atom -mtune=atom -fomit-frame-pointer -mssse3 -mieee-fp -mfpmath=sse -fexcess-precision=fast -mpush-args -mhard-float -fPIC ...

.Ltext0:
    .p2align 4,,15
    .type   strlen16, @function
strlen16:
.LFB20:
    .cfi_startproc
.LVL0:
    mov edx, DWORD PTR 4[esp]
    xor eax, eax
    test    edx, edx
    je  .L4
    .p2align 4,,15
.L3:
.LVL1:
    lea eax, 1[eax]
.LVL2:
    cmp WORD PTR -2[edx+eax*2], 0
    jne .L3
    ret
.LVL3:
    .p2align 4,,7
    .p2align 3
.L4:
    ret
    .cfi_endproc
.LFE20:
    .size   strlen16, .-strlen16

ここでIntelの分解:

static inline size_t strlen16(register const char16_t * string) {
   0:   8b 54 24 04             mov    edx,DWORD PTR [esp+0x4]
    if (!string) return 0;
   4:   31 c0                   xor    eax,eax
   6:   85 d2                   test   edx,edx
   8:   74 16                   je     20 <strlen16+0x20>
   a:   8d b6 00 00 00 00       lea    esi,[esi+0x0]
    register size_t len = 0;
    while(string[len++]);
  10:   8d 40 01                lea    eax,[eax+0x1]
  13:   66 83 7c 42 fe 00       cmp    WORD PTR [edx+eax*2-0x2],0x0
  19:   75 f5                   jne    10 <strlen16+0x10>
  1b:   c3                      ret    
  1c:   8d 74 26 00             lea    esi,[esi+eiz*1+0x0]
    return len;
}
  20:   c3                      ret    
  21:   eb 0d                   jmp    30 <AnonymousFunction0>
  23:   90                      nop
  24:   90                      nop
  25:   90                      nop
  26:   90                      nop
  27:   90                      nop
  28:   90                      nop
  29:   90                      nop
  2a:   90                      nop
  2b:   90                      nop
  2c:   90                      nop
  2d:   90                      nop
  2e:   90                      nop
  2f:   90                      nop
于 2014-03-02T13:48:53.237 に答える
0

Unicodeの場合、最初のバイトがゼロになる可能性があるため、2バイトを読み取り、両方がゼロであるかどうかを確認する必要があります。

完璧な解決策ではありません(実際には一種の奇妙な解決策):

size_t strlen16(const char16_t* str16) {
    size_t result = 0;
    char* strptr = (char*) str16;
    char byte0, byte1;

    if(str16 == NULL) return result;

    byte0 = *strptr;
    byte1 = *(strptr + 1);

    while(byte0|byte1) {
        strptr += 2;
        byte0 = *strptr;
        byte1 = *(strptr + 1);
        result++;
    }
    return result;
}
于 2013-01-25T19:15:26.720 に答える
0

Windowsには、がありwcslen()ます。

プラットフォームに関係なく、char16_tは使用しない方がよいでしょう。言語でそれを持っていることは標準委員会の側の過ちであると私は信じます。

于 2013-01-25T19:41:07.757 に答える