字符串在内存中可以使用链式结构也可以使用线性结构。我们将用线性结构来存放字符串(以后的内容涉及到字符串在内存中均为线性存储方式),并对字符串进行相关操作。
首先来看一下字符串在内存中的存放格式:
char *str = "Hello World!";
在内存中定义了一个指针变量str,它的值是0x2000(地址0x2000是假设的),也就是"Hello World!"这个字符串的首地址。下面我们来看一下对于str指针可以取得这个字符串中字符的相关计算方法:
*str == 'H'; str[0] == 'H'; *(str + 1) = 'e'; str[1] = 'e';
也就是说对于线性存储的字符串,可以对指针直接解引用*str,也可以将其当作数组用下标的方式进行取值。下面来看一下字符串的相关操作:
//计算字符串长度 int str_length(char *str) { if (str == null) { return 0; } //计算字符串长度 int length = 0; while (*str != '\0') { length++; str++; } return length; } //拷贝字符串 bool str_copy(char *str_target, char *str_source) { if (str_target == null || str_source == null) { return false; } //复制字符串 while (*str_source != '\0') { *str_target++ = *str_source++; } *str_target = '\0'; return true; } //比较两个字符串,如果str0 < str1 返回-1, 如果相等返回 0 否则返回 1 int str_compare(char *str0, char *str1) { if (str0 == null || str1 == null) { return 0; } //比较 while (*str0 != '\0' && *str1 != '\0') { //小于 if (*str0 < *str1) { return -1; } //大于 else if (*str0 > *str1) { return 1; } str0++; str1++; } //如果都结束,表示相等 if (*str0 == '\0' && *str1 == '\0') { return 0; } //如果str0结束str1没结束,表示小于 else if (*str0 == '\0') { return -1; } //str1结束str0没结束,表示大于 else { return 1; } } //将str0和str1连接,结果用str_new返回 bool str_concat(char *str_new, char *str0, char *str1) { if (str_new == null || str0 == null || str1 == null) { return false; } //复制str0 while (*str0 != '\0') { *str_new++ = *str0++; } //复制str1 while (*str1 != '\0') { *str_new++ = *str1++; } //结尾符 *str_new = '\0'; return true; } //将str从pos位置切割出len个字符到sub中 bool str_sub(char *sub, char *str, int pos, int len) { if (sub == null || str == null || pos < 0 || len == 0) { return false; } //从pos位置开始 str += pos; int i = 0; //截取len长度的子串 while (*str != '\0') { if (i++ >= len) { break; } *sub++ = *str++; } //结束符 *sub = '\0'; return true; } //返回str_ind在str中第pos个字符后出现的位置 int str_index(char *str, char *str_ind, int pos) { if (str_ind == null || str == null || pos < 0) { return -1; } //计算长度 int length = str_length(str); int len = str_length(str_ind); if (pos >= length) { return -1; } //从pos开始计算 str += pos; int ind = 0; while (*str != '\0') { //查找子串 bool same = true; for (int i = 0; i < len; ++i) { //如果在子串长度内发现不同字符,表示当前子串查找失败 if (str[i] != str_ind[i]) { same = false; break; } } //如果存在子串,返回位置 if (same) { return ind + pos; } ind++; str++; } return -1; } //在str在第pos个位置上插入字符串str_ins bool str_insert(char *str, char *str_ins, int pos) { if (str == null || str_ins == null || pos < 0) { return false; } //计算长度 int len = str_length(str); if (pos >= len) { return false; } //计算长度 int len_ins = str_length(str_ins); // 处理\0所以len - pos + 1 for (int i = len + len_ins, j = 0; j < len - pos + 1; i--, j++) { //向后复制 str[i] = str[i - len_ins]; } for (int i = 0; i < len_ins; i++) { //插入子串 str[pos + i] = str_ins[i]; } return true; } //删除str中第pos位置后len个字符 bool str_delete(char *str, int pos, int len) { if (str == null || pos < 0 || len < 0) { return false; } //计算长度 int length = str_length(str); //向前复制len长度 for (int i = 0; i < length - pos; ++i) { str[pos + i] = str[pos + i + len]; } //结束符 str[length - len] = '\0'; return true; }
再来写一个main函数测试字符串功能函数:
int main(int argc, char **args) { char *str = (char *) malloc(100); str_copy(str, "Hello World!"); printf("%s\n", str); int cmp0 = str_compare("abcde", "abcde"); int cmp1 = str_compare("abcde", "abcdf"); int cmp2 = str_compare("abcdf", "abcde"); int cmp3 = str_compare("abcde", "abcdef"); int cmp4 = str_compare("abcdef", "abcde"); printf("%d %d %d %d %d\n", cmp0, cmp1, cmp2, cmp3, cmp4); str_concat(str, "Hello ", "World!"); printf("%s\n", str); str_sub(str, "Hello World!", 7, 2); printf("%s\n", str); int ind0 = str_index("Hello World!", "o", 0); int ind1 = str_index("Hello World!", "o", 5); printf("%d %d\n", ind0, ind1); str_copy(str, "Hello World!"); str_insert(str, "My Beautiful ", 6); printf("%s\n", str); str_delete(str, 6, 3); printf("%s\n", str); str_delete(str, 6, 10); printf("%s\n", str); free(str); return 0; }
运行结果:
Hello World! 0 -1 1 -1 1 Hello World! or 4 7 Hello My Beautiful World! Hello Beautiful World! Hello World!
本例代码:
code path chapter.03/e.g.3.1/ https https://github.com/magicworldos/datastructure.git git git@github.com:magicworldos/datastructure.git subverion https://github.com/magicworldos/datastructure
Copyright © 2015-2023 问渠网 辽ICP备15013245号