关于C语言strxfrm()函数的两大技术疑问
1. 返回值问题
根据函数定义,strxfrm()应返回转换后字符串(目标缓冲区)的长度(不含终止空字符),但测试发现返回值是源字符串的长度,具体测试如下:
测试代码
#include <stdio.h> #include <string.h> int main() { char arr1[100] = "Hello, World!", arr2[] = "Baxlazazasad"; int retValue = strxfrm(arr1, arr2, 3); printf("Content of arr1:\t%s\nLength of arr1:\t%lu\n\nContent of arr2:\t%s\nLength of arr2:\t%lu\n\n", arr1, strlen(arr1), arr2, strlen(arr2)); printf("retValue =\t%i\n", retValue); return 0; }
测试输出
Content of arr1: Baxlo, World!
Length of arr1: 13Content of arr2: Baxlazazasad
Length of arr2: 12retValue = 12
原因解释:strxfrm()的返回值是源字符串经区域设置规则转换后的总长度(不含终止符),和传入的目标缓冲区大小无关。哪怕你只给了3字节的缓冲区,它依然会返回完整转换后的字符串长度——这个值的作用是告知你:若要完整存储转换结果,需要多大的缓冲区空间。你看到返回12,是因为当前默认C locale下,转换后的字符串长度和原字符串完全一致。
2. 功能归类问题
为什么strxfrm()被归为字符串比较类函数,而非字符串复制类?
核心原因:strxfrm()的设计目的不是复制字符串,而是根据当前区域设置的排序规则,将源字符串转换为可直接用strcmp()比较的标准化形式。复制只是转换过程中的附带动作,而非核心功能。
在默认C locale下,转换后的字符串和原字符串完全相同,所以看起来像复制,但这是特例。比如在法语locale中,带重音的字符会被转换为对应的排序键,此时转换后的字符串和原字符串差异很大,但用strcmp()比较转换结果就能得到符合当地语言习惯的排序结果——这才是strxfrm()的真正价值,也是它被归为比较类函数的原因。
内容的提问来源于stack exchange,提问作者Sandrious

