在php中有str_replace()可以将字符串中的某些内容替换成另外的内容,但c并没有提供这样的功能。
因为c要管理内存,当替换成的字符串长度大于要替换的字符串长度时,原来存放数据的空间是否足够以供替换后的数据存放是个问题。为此:C可以实现返回一个动态分配内存的空间,存放替换后的数据。
另外,如果不想使用新空间存放,那么必须保证存放数据的内存足够大,比如如果肯定数据替换后不会超过10KB,那么可以先分配10KB。
具体代码如下:
#include <stdio.h> #include <stdlib.h> #include <string.h> /** * 统计key在data中出现的次数 * @param data 待查找的字符串 * @param key 要查找的字符串 * @return key在data中出现的次数 */ int _count_string(char *data, char *key) { int count = 0; int klen = strlen(key); char *pos_start = data, *pos_end; while (NULL != (pos_end = strstr(pos_start, key))) { pos_start = pos_end + klen; count++; } return count; } /** * 将data中的rep字符串替换成to字符串,以动态分配内存方式返回新字符串 * 这个函数不需要保证data能保证容量。 * @param data 待替换某些字符串的数据 * @param rep 待替换的字符串 * @param to 替换成的字符串 * @param free_data 不为0时要释放data的内存 * @return 返回新分配内存的替换完成的字符串,注意释放。 */ char *malloc_replace(char *data, char *rep, char *to, int free_data) { int rep_len = strlen(rep); int to_len = strlen(to); int counts = _count_string(data, rep); printf("counts = %d\n", counts); int m = strlen(data) + counts * (to_len - rep_len); char *new_buf = (char *) malloc(m + 1); if (NULL == new_buf) { free(data); return NULL; } memset(new_buf, 0, m + 1); char *pos_start = data, *pos_end, *pbuf = new_buf; int copy_len; while (NULL != (pos_end = strstr(pos_start, rep))) { copy_len = pos_end - pos_start; strncpy(pbuf, pos_start, copy_len); pbuf += copy_len; strcpy(pbuf, to); pbuf += to_len; pos_start = pos_end + rep_len; } strcpy(pbuf, pos_start); if (free_data) free(data); return new_buf; } /** * 将data中的rep字符串替换成to字符串 * 注意保证data空间足够替换完成后的字符串长度 * @param data 待替换某些字符串的数据 * @param rep 待替换的字符串 * @param to 替换成的字符串 * @return 无 */ void normal_replace(char *data, char *rep, char *to) { char *new_buf = malloc_replace(data, rep, to, 0); if (NULL != new_buf) { strcpy(data, new_buf); free(new_buf); } } int main(int argc, char **argv) { char buf[4096]; char *rep = "{subject}"; char *to = "留香的美好"; strcpy(buf, "Subject: {subject}, body:Subject2:{subject}; end"); printf("%s\n", buf); normal_replace(buf, rep, to); printf("%s\n", buf); return 0; }