正如问题所说:
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
。
对于包含BMP
之外字符的UTF-16
字符串,这两者完全不同。
这是你的基本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中每个字符2个字节或BMP外每个字符4个字节),这些function不包含这些内容。
#include #include #include #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位Intel Atom组件视图:
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
这里是英特尔反汇编:
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 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 1b: c3 ret 1c: 8d 74 26 00 lea esi,[esi+eiz*1+0x0] return len; } 20: c3 ret 21: eb 0d jmp 30 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
您需要读取2个字节并检查它们是否都为零,因为在unicode中,第一个字节可以为零。
不是一个完美的解决方案(实际上是一种奇怪的解决方案):
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; }
在Windows上,有wcslen()
。
无论平台如何,最好不要使用char16_t。 我认为标准委员会在语言中存在错误。
std :: char_traits有这个。
#include std::char_traits::length(yourchar16pointerhere);
以上就是c/c++开发分享是否有一个与char16_t一起使用的strlen()?相关内容,想了解更多C/C++开发(异常处理)及C/C++游戏开发关注计算机技术网(www.ctvol.com)!)。
本文来自网络收集,不代表计算机技术网立场,如涉及侵权请联系管理员删除。
ctvol管理联系方式QQ:251552304
本文章地址:https://www.ctvol.com/c-cdevelopment/545697.html