08-C语言字符串

字符串

  • 将字符串到一起就是字符串,有序 / 同类型的 ---> 数组
  • 其实C语言中的字符串就是一个特殊的数组而已
  • 如果用数组表示字符串,那么数组必须是char类型,而且最后一个元素必须是\0
  • 在c语言中除了可以用字符数组来表示字符串以外,还可以用双引号" " 来表示字符串
以下就是一个字符串
char str1[] = {'c','w','w','\0'};

// 如果在定义的同时部分初始化,没有被赋值的元素会被自动赋值为0;
char str2[5] = {'c','w','w'};

char str3[] = "cww"; // 底层就是 {'c','w','w','\0'};

以下是一个字符数组,不是字符串
char str4[] = {'c','w','w'};

printf("str1 = %s\n",str1); // cww
printf("str2 = %s\n",str2); // cww
printf("str3 = %s\n",str3); // cww
printf("str4 = %s\n",str4); // cwwcww

image
  • 特别注意:字符串在内存中存储是连续的,只有遇到\0接结束
image

字符串常用方法

puts

  • 格式: puts(字符数组名)
  • 功能: 把字符数组中的字符串显示到控制台
  • 优点: 可以换行,可以是任意元素地址
```
char str1[] = "cww";
// printf + %s 输出不会自动换行,必须手动添加\n
printf("str = %s\n",str);
puts(str); // 会自动换行
printf("被换行");
```
![image](http://upload-images.jianshu.io/upload_images/7924287-73fd597a05f01451.jpg?imageMogr2/auto-orient/strip%7CimageView2/2/w/1240)

gets

  • 格式:gets(字符数组名);
  • 功能:从键盘中输入一个字符串
```
char str2[10];
// scanf接收用户输入,
// scanf输入的数据中不能有空格/TAB/回车
scanf("%s", &str2);

//gets接收字符串,可以输入空格/TAB
// gets(str2);
printf("str2 = %s\n", str2);
```

strlen

  • 功能:计算字符串的长度
  • 利用sizeof计算字符串长度
```
char str1[] = "cww";
int len = sizeof(str1) / sizeof(str1[0]); 
// 注意这里计算是字符串占用内存单元的字节数
// 实际是len = len -1;
```

- 利用系统函数strlen计算
    - 注意: **在使用strlen要引入头文件 #include <string.h>;**
```
char str2[] = "cww";
strlen(str2);
```    
  • 自定义strlen函数
```
/**
 * @brief getStrlen  实现strlen函数
 * @param str        传入字符串
 * @return  len 长度
 */
int getStrlen (char str[]){
    int len = 0;
    while(str[len] != '\0'){
        len++;
    }
    return len;
}
```
  • 指针版
```
/**
 * @brief getStrlen  实现strlen函数
 * @param str        传入字符串
 * @return  len 长度
 */
int myStrlen(char *str){
    int index = 0;
    while(*str++){
        index++;
    }
    return index;
}
```
  • 注意点: *str++ 是先将地址加1在访问地址所存储的内容;
```
/**
 * @brief getStrlen  实现strlen函数
 * @param str        传入字符串
 * @return  len 长度
 */
int myStrlen(char *str){
    char *startP = str;
    while(*str++);
    str--;
    return str - startP;

}

```

strcat

  • 注意: 在使用strlen要引入头文件 #include <string.h>;
  • 格式:strcat(字符数组名1,字符数组名2);
  • 功能:把字符数组2中的字符串连接到字符数组1中字符串的后面,
  • 注意点:前面的数组必修足够长,否则在企业中会引发一些未知的BUG
```

char str1[10] = "cww";
char str2[4] = "ppp";
strcat(str1, str2);
printf("str1 = %s\n",str1);  // cwwppp

```
  • 自己封装的strcat函数
```

/**
 * @brief myStrcat  实现字符串的拼接
 * @param str1      传入字符串1
 * @param str2      传入字符串2
 */
void myStrcat(char *str1, char *str2){
    //printf("%s\n",str1);
    int index = 0;
    // 取出str1中存储的地址
    //printf("str1 = %p\n",str1);
    //printf("str1 = %c\n",*str1);
    while(*str1++) {
        index++;
    }
    //printf("str1 = %p\n",str1);
//    while (str1[index] != '\0') {
//        index++;
//    }
    printf("index = %i\n", index);
    int value = 0;
    while(str2[value] != '\0'){
        str1[index] = str2[value];
        index++;
        value++;
    }

    // printf("index = %i\n", index);
    str1[index] = '\0';
}
```
  • 指针版
```
/**
 * @brief myStrcat    指针优化的strcat函数
 * @param str1       传入字符串1
 * @param str2      传入字符串2
 */
void myStrcat(char *str1, char *str2){
    while(*str1++);
    str1--;
    while(*str2){
        *str1 = *str2;
        str1++;
        str2++;
    }
    *str1 = '\0';
}
```

strcpy

  • 注意: 在使用strlen要引入头文件 #include <string.h>;
  • 格式: strcpy(字符数组1,字符数组名2);
  • 功能: 把字符数组2中的字符串拷贝到字符数组1中.字符串结束标志'\0'也一同拷贝.
  • 注意点:前面的数组必修足够长,否则在企业中会引发一些未知的BUG
```
char str1[10] = "cww";
char str2[4] = "ppp";
strcpy(str1,str2);
printf("str1 = %s\n",str1); // ppp
printf("str2 = %s\n",str2); // ppp
```
  • 自定义strcpy函数
```
#include <stdio.h>
#include <string.h>
void myStrcpy(char *str1, char *str2);
int main()
{
    char str1[] = "cwww";
    char str2[] = "ppppp";
    //strcpy(str1, str2);
    myStrcpy(str1, str2);
    printf("str1 = %s\n", str1);
    return 0;
}

/**
 * @brief myStrcpy  实现strcpy函数
 * @param str1      传入字符串1
 * @param str2      传入字符串2
 */
void myStrcpy(char *str1, char *str2){
    int index = 0;
    while (str2[index] != '\0') {
        str1[index] = str2[index];
        index++;
    }
    str1[index] = '\0';
}

```
  • 指标版
```
/**
 * @brief myStrcpy  指针实现strcpy函数
 * @param str1      传入字符串1
 * @param str2      传入字符串2
 */
void myStrcpy(char *str1, char *str2){
    while(*str2){
        *str1 = *str2;
        str1++;
        str2++;
    }
    *str1 = '\0';
}
```

strcmp

  • 注意: 在使用strlen要引入头文件 #include <string.h>;
  • 格式: strcmp(字符数组名1,字符数组名2)
  • 功能: 按照ASCII码顺序比较两个数组中的字符串,并右函数返回值返回比较结果
    • 字符串1 = 字符串2, 返回值 = 0;
    • 字符串1 > 字符串2, 返回值 > 0;
    • 字符串1 < 字符串2, 返回值 < 0;
    • 如果前面的内容都相同, 第一个参数的个数小于第二个参数, 返回 -1 负数
    • 如果前面的内容都相同, 第一个参数的个数大于第二个参数, 返回 1 正数
```
char str1[10] = "124";
char str2[4] = "123";
int res = strcmp(str1,str2);
printf("res = %i\n", res);  // 1
```
  • 自定义strcmp
```
#include <stdio.h>
#include <string.h>
int myStrcmp(char *str1, char *str2);
int main()
{
    char str1[] = "1224";
    char str2[] = "12233";
    int res1 = strcmp(str1, str2);
    printf("res1 = %i\n", res1);

    int res2 = myStrcmp(str1, str2);
    printf("res2 = %i\n", res2);
    return 0;
}

/**
 * @brief myStrcmp  实现strcmp函数
 * @param str1      传入第一个字符串
 * @param str2      传入第二个字符串
 * @return 
 */
int myStrcmp(char *str1, char *str2){
    int index = 0;
    while (str1[index] != '\0' || str2[index] != '\0') {
        if(str1[index] > str2[index]){
            return 1;
        }else if(str1[index] < str2[index]){
            return -1;
        }
        index++;
    }
    return 0;
}

```
  • 指针版
```

/**
 * @brief myStrcmp  指针实现strcmp函数
 * @param str1      传入第一个字符串
 * @param str2      传入第二个字符串
 * @return
 */
int myStrcmp(char *str1, char *str2){
    while (*str1 || *str2) {
        if(*str1 > *str2){
            return 1;
        }else if(*str1 < *str2){
            return -1;
        }
        str1++;
        str2++;
    }
    return 0;
}
```

字符串数组

  • 字符串数组其实就是定义一个数组保存所有的字符串
char names1[2][6] = {{'c','w','w','\0'},{'p','p','p'}};
char names2[2][6] = {{"cww"},{"ppp"}};
char names3[2][6] = {"cww","ppp"};

  • 指针定义字符串
char *str1 = "cww";
char *str2 = "abc";
char *str3 = "def";
char *str{
    str1,
    str2,
    str3
};

// 字符串数组的第二种格式
char *str[] = {
    "cww",
    "abc",
    "def"
};
最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 202,802评论 5 476
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 85,109评论 2 379
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 149,683评论 0 335
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 54,458评论 1 273
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 63,452评论 5 364
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 48,505评论 1 281
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 37,901评论 3 395
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 36,550评论 0 256
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 40,763评论 1 296
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 35,556评论 2 319
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 37,629评论 1 329
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 33,330评论 4 318
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 38,898评论 3 307
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 29,897评论 0 19
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 31,140评论 1 259
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 42,807评论 2 349
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 42,339评论 2 342

推荐阅读更多精彩内容