/*********************************************
* @brief 按照语言环境转换字符串
* @param dest 目标地址
* @param src 源字符串
* @param count 最多复制的字节数
* @return 目标地址
********************************************/
size_t strxfrm(char* restrict dest, const char* restrict src, size_t count);
!subtitle:说明
按照语言环境转换字符串,结果保留 count 个字节。
如果结果长度大于等于 count 字节,存储到 dest 时将缺少结尾的 0。
转换结果主要用于比较和排序,通常是不可读的(显示为乱码)。
!subtitle:参数
dest - 指向要复制到的内存地址
src - 指向要被复制的字符串
count - 最多保留的字节数,包括结尾的 0
!subtitle:返回值
转换后的字符串的长度,不包括结尾的 0。
#include <stdio.h>
#include <stdlib.h>
#include <locale.h>
#include <string.h>
int main(void)
{
if (setlocale(LC_COLLATE, "zh_CN.UTF-8") == NULL) // 设置语言环境
{
fprintf(stderr, "语言环境设置失败\n");
return EXIT_FAILURE;
}
const char* in1 = "你好";
const char* in2 = "世界";
size_t out1_len = strxfrm(NULL, in1, 0); // 获取结果长度,不含结尾的 0
size_t out2_len = strxfrm(NULL, in2, 0);
char* out1 = malloc(out1_len + 1); // 分配内存
char* out2 = malloc(out2_len + 1);
strxfrm(out1, in1, out1_len + 1); // 转换
strxfrm(out2, in2, out2_len + 1);
// 比较原字符串
if (strcmp(in1, in2) < 0)
{
printf("按照编码字节排序,\"%s\" 在 \"%s\" 之前\n", in1, in2);
}
else
{
printf("按照编码字节排序,\"%s\" 在 \"%s\" 之后\n", in1, in2);
}
// 比较转换后的字符串
if (strcmp(out1, out2) < 0)
{
printf("按照汉语拼音排序,\"%s\" 在 \"%s\" 之前\n", in1, in2);
}
else
{
printf("按照汉语拼音排序,\"%s\" 在 \"%s\" 之后\n", in1, in2);
}
free(out1); // 释放内存
free(out2);
return EXIT_SUCCESS;
}
说明:
首先通过 setlocale 设置语言环境
在转换前通过 strxfrm(NULL, src, 0) 获取结果字符串长度
分配的内存长度比结果字符串长度多一个字节,用于包含结尾的 0
中文转换后按照汉语拼音排序
运行结果:
按照编码字节排序,"你好" 在 "世界" 之后
按照汉语拼音排序,"你好" 在 "世界" 之前
C17 standard (ISO/IEC 9899:2018):
7.24.4.5 The strxfrm function (p: 267)
C11 standard (ISO/IEC 9899:2011):
7.24.4.5 The strxfrm function (p: 366-367)
C99 standard (ISO/IEC 9899:1999):
7.21.4.5 The strxfrm function (p: 329-330)
C89/C90 standard (ISO/IEC 9899:1990):
4.11.4.5 The strxfrm function