C语言字符串比较异常:CodeWars编码函数结果对比失败求助
C字符串比较返回FALSE的问题解决
问题背景
我正在完成CodeWars的一道练习题,需要实现encode()函数将字符串中的小写元音字母按规则替换为数字:a→1、e→2、i→3、o→4、u→5,例如encode("hello")应返回"h2ll4"。我实现了函数,但在对比结果时遇到问题。
我的代码
#include <stdbool.h> #include <stdio.h> #include <stdlib.h> #include <string.h> char *encode(const char *string) { char *string_encoded; string_encoded = malloc(strlen(string) + 1); memcpy(string_encoded, string, strlen(string) + 1); for (int i = 0; i < strlen(string); i++) { switch (string[i]) { case 'a': string_encoded[i] = '1'; break; case 'e': string_encoded[i] = '2'; /* code */ break; case 'i': string_encoded[i] = '3'; /* code */ break; case 'o': string_encoded[i] = '4'; /* code */ break; case 'u': string_encoded[i] = '5'; /* code */ break; } } return string_encoded; } int main(int argc, char const *argv[]) { char *encoded_string = encode("hello"); char *valide_encoded_string = "h2ll4"; printf((encode("hello") == "h2ll4") ? "TRUE\n" : "FALSE\n"); // print FALSE printf((encode("hello") == valide_encoded_string ) ? "TRUE\n" : "FALSE\n"); // print FALSE //printf((encode("How are you today?") == "H4w 1r2 y45 t4d1y?") ? "TRUE\n" : "FALSE\n"); return 0; }
问题详情
使用==比较encode函数返回的字符串与正确字符串时始终返回FALSE,通过GDB查看发现两个字符串的内存地址不同:
encoded_string : 0x5555555592a0 "h2ll4" valide_encoded_string : 0x555555556072 "h2ll4"
我原以为是字符串末尾的空字符问题,但已使用strlen()+1复制字符串,不清楚对比失败的原因,希望得到帮助。
问题原因
在C语言中,字符串本质是指向字符数组的指针。用==比较两个字符串时,实际比较的是指针的内存地址,而不是字符串的内容:
encode()函数返回的是通过malloc()在堆上分配的内存地址,每次调用encode()都会分配新的堆内存,地址自然不同。- 字符串字面量(比如
"h2ll4")存储在程序的只读数据段,地址是固定的,但和堆内存地址完全不重合。
所以即使两个字符串内容完全一样,地址不同时==就会返回FALSE。
解决方案
1. 使用strcmp()比较字符串内容
C标准库提供的strcmp()函数专门用于比较字符串内容:
- 如果两个字符串内容相等,
strcmp(a, b)返回0; - 如果
a字典序小于b,返回负数; - 如果
a字典序大于b,返回正数。
修改main函数中的比较逻辑:
int main(int argc, char const *argv[]) { char *encoded_string = encode("hello"); const char *valid_encoded_string = "h2ll4"; // 正确的比较方式 if (strcmp(encoded_string, valid_encoded_string) == 0) { printf("TRUE\n"); } else { printf("FALSE\n"); } // 记得释放malloc分配的内存,避免泄漏 free(encoded_string); encoded_string = NULL; return 0; }
2. 额外优化建议
- 避免循环中重复计算strlen:每次调用
strlen()都会遍历字符串到末尾,把长度存到变量里可以提升效率:char *encode(const char *string) { size_t len = strlen(string); char *string_encoded = malloc(len + 1); memcpy(string_encoded, string, len + 1); for (size_t i = 0; i < len; i++) { // 替换逻辑不变 } return string_encoded; } - 检查malloc返回值:如果内存分配失败,
malloc()会返回NULL,建议添加错误处理逻辑。
内容的提问来源于stack exchange,提问作者RaiZy_Style
相关产品推荐
相关产品推荐

