我的功能如下:

void utf8_trim_end(char *data, int length){
  int bytecount = 1;
  int idx = length;
  char *current = data;
  for (int i = 0; i < length; i += bytecount){
     if (!iswhitespace(&data[i])){
        idx = i;
     }
     bytecount = utf8_bytecount(&data[i], length-i);
  }
  data[idx] = 0;
}

正如您所看到的,为了确保我们查看多字节字符的开头,我们从开头开始,然后遍历.这是有效的,但对于长弦来说,它是缓慢的.我想知道是否有一种公认的方法可以从最后开始并从那里向后工作?(另外,我不想找图书馆,我想自己做这件事)

推荐答案

你们can个人走到最后,倒着干.

所有UTF-8多字节字符都表示为一个开始字节,后跟多个"延续"字节,其数目可以通过判断开始字节来确定.所有的连续字节都是0b10xx xxxx的形式.因此,无论您在UTF-8字符串中的哪个位置,如果您是在一个连续字节上,您都可以向前扫描or backwards以跳过连续字节并找到开始字节.

从UTF-8流中查找和识别Unicode空格字符,向后阅读可能会有点麻烦,但留给读者作为练习!

(编码在Good Wikipedia article中描述).


(编辑后添加:)

如果您(或其他任何人)所需要的只是一个快速而肮脏的解决方案,那么,由于ASCII范围中的代码点在UTF-8中被编码为相应的字节(即,空格字符仅被编码为0x20),因此您可以只通过go 除具有Ctype isspace()的ASCII空白来从UTF-8编码的字符串中go 除most个尾随空白.

But,如果它matters,空白被删除,在某种意义上说,有人可能想破解的过程,那么你仍然必须做它"适当". 这是因为字符有可能被编码得"过长"(尽管不推荐):空格字符可能会出现为多字节序列0xC0 0xA00xE0 0x80 0xA00xF0 0x80 0x80 0xA0,所有这些都将解码为空格字符,从而欺骗快速而肮脏/天真的空格剥离器.

(我现在要闭嘴了,但我最近不得不以娱乐的方式与这些东西争论,所以它仍然在我的脑海中记忆犹新)

C++相关问答推荐

C中的ATONE会扰乱SEN/CLUTE GMS应用程序中的其他字符串

如何启用ss(另一个调查套接字的实用程序)来查看Linux主机上加入的多播组IP地址?

有效地计算由一组点构成的等边三角形和等腰三角形的数量

sizeof结果是否依赖于字符串的声明?

C中是否有语法可以直接初始化一个常量文本常量数组的 struct 成员?

为什么双重打印与C中的float具有不同的大小时具有相同的值?

C:二进制搜索和二进制插入

Ruby C Api处理异常

具有交换链获取和命令缓冲区提交的同步-危险-读后写错误

双指针指向常量双指针的指针类型赋值不兼容

在CLANG中调试预处理器宏

使用sscanf获取零个或多个长度的字符串

对于C中给定数组中的每个查询,如何正确编码以输出给定索引范围(1到N)中所有数字的总和?

如何使用libgpio(d)为Raspberry Pi编译C程序?

为什么realloc函数在此代码中修改变量?

unions 的原子成员是个好主意吗?

C中的空指针是什么(_N)?

哪些C++功能可以在外部C块中使用

即使客户端不发送数据,也会发生UNIX套接字读取

C23 中的 [[reproducible]] 和 [[unsequenced]] 属性是什么?什么时候应该使用它们?