C 字符串

字符串

  • 1.概念

    • 一组连续的字符
    • 必须以\0字符做结尾
    • 存放在一组连续的字符类型存储区里
  • 2.分类(字符串存储方式不同)

    • 字符串字面值
      • 一对双引号中间夹杂着一堆字符
      • “asjkdh”, 编译器在编译时会自动在最后一个字符后面加 \0, 并且会把这个字符串字面值替换成第一个字符所在存储区的地址,字符串字面值编译完以后其实是一个地址数据
      • 字符串字面值内容在程序执行过程中不能修改,所以如果写了两个一样的字符串字面值,他们在程序中其实是同一个(在代码段中)
      • “abc”“def”,两个字符串字面值并列写在一起,编译器会把这两个字符串字面值合并成一个 "abcdef’
    • 字符数组里的字符串
      • 字符数组天然就包含了一组连续字符类型的存储区,天然适合存放字符串(前提是这个数组里包含/0字符,不然字符数组里的内容没法当做字符串来使用
      • 字符数组里的字符串内容是可以被修改的
  • 3.使用方法

    • 不可以使用操作符来处理字符串(比如+)
    • C语言专门提供了一组标准函数来处理字符串(需要包含string.h头文件)
  • 4.操作字符串函数

    • 4.1 strlen
      • 获得字符串里有效字符的个数(\0字符前面的字符)
      • 参数是一个字符串,返回值就是得到的有效字符串个数
      • strlen(”abcdef“)
#include <stdio.h>
#include <string.h>
int main() {
    //声明字符数组并用字符串字面值给字符数组初始化,把字符串字面值里的所有有效数字放进数组里
    //编译的时候会在"abc"的末尾加上一个\0字符,初始化的时候也会把\0放到数组里,这样字符数组里的内容才能当做字符串来使用
    char str[10] = "abc"; //    //str[3]到str[9]的存储区里都放的0
    int size = 0;
    //字符数组里已经放好的字符串,然后把字符数组当做字符串交给strlen使用
    size = strlen(str);
    printf("str[3]是%d\n", str[3]);
    printf("str[4]是%d\n", str[4]);
    printf("str[10]是%d\n", str[9]);
    printf("size是%d\n",size);
    return 0;
}

/*
output:
str[3]是0
str[4]是0
str[10]是0
size是3
*/
  • 4.2 strcat
    • 把第一个字符串的内容追加到另外一个字符串的末尾
    • 需要两个字符串做参数,第一个字符串必须是字符数组里的字符串(因为字符串字面值内容在程序执行过程中不能修改)
    • 把第二个参数里的有效字符追加到第一个参数的末尾
    • 返回值就是第一个参数
    • strcat(str, “xyz”)
#include <stdio.h>
#include <string.h>
int main() {
    char str[10] = "abc"; 
    char *p_ch = NULL;
    p_ch = strcat(str, "def");
    //%s 占位符比较特殊,可以显示多个连续字符类型存储区内容 
    //它是从一个地址开始的,一个字符一个字符的显示,直到碰到\0字符的存储区为止
    printf("%s\n", p_ch);
    printf("%s\n", str);

    return 0;
}

/*
output:
abcdef
abcdef
*/
  • 4.3 strncat

    • 功能和strcat类似
    • 多一个整数类型参数表示最多追加的字符个数
    • strncat(str, “asdfsd”, 2); //为了避免str存储区不够用的情况,只是把"as"追加上去
  • 4.4 strcmp

    • 比较两个字符串大小
    • 从第一个字符开始一对一对的比较,比较的依据就是ASCII码,ASCII大的字符所在的字符串就大
    • 返回值表示比较结果,1表示前一个字符串大,-1表示后一个字符串大,0表示一样大
    • strcmp(“abc”, “def”);
  • 4.5 strncmp

    • 功能和strncmp类似
    • 可以只比较前n个字符
    • strncmp(“abc”, “abd”, 2);
  • 4.6 strcpy

    • 可以把一个字符串复制到字符数组里
    • 如果后面的字符串的内容超过数组所能容纳的范围,有可能会发生严重的错误
#include <stdio.h>
#include <string.h>
int main() {
    char str[10] = "abcdef"; 
    char *p_ch = NULL;
    //除了会复制字符串的有效数字以外,还会把字符串后面的\0字符也复制到数组里去
    //复制完以后str字符数组的前4位存储区是x, y, z, \0,后面的存储区还留有原来的一些字符
    //因为它们处在\0后面,已经不被当做字符串的有效字符看待
    p_ch = strcpy(str, "xyz");
    printf("%s\n", p_ch);
    printf("%s\n", str);
    return 0;
}

/*
output:
xyz
xyz
*/
  • 4.7 strncpy

    • 功能和strcpy类似
    • 可以只复制前n个字符
    • 有可能不复制"\0"字符
  • 4.8 memset

    • 用来把一组字符类型存储区的内容设置成同一个字符
    • memset(str, ‘x’, 9); //前9个字符类型存储区里的内容都设置成’x’
  • 4.9 strstr

    • 在一个字符串里查找另外一个字符串内容的位置
    • 如果没有就返回NULL
#include <stdio.h>
#include<string.h>
int main() {
    char *p_ch = NULL;
    //找到第二个字符串的第一个字符d在第一个字符串中存储区的地址并返回
    p_ch = strstr("abcdefghigklmn", "def"); //不加(char *)会报错,可能是因为strstr的返回值是 const char *
    printf("%s\n", p_ch);
    return 0;
}

// output: defghigklmn
  • 5.0 下面两个操作字符串的函数不要求包含string.h头文件
    • sprintf 可以把多个数字组合成一个字符串记录到字符数组里
    • sscanf 可以从字符串里获得多个数字并记录到存储区里
#include <stdio.h>

int main() {
    char str[10] = {0};
    char ch = 0;
    int val = 0;
    float fval = 0.0f;
    
    //printf会先把3个数字按照格式要求转换成字符,然后再显示在屏幕上
    printf("%c %d %g \n", 'r', 87, 5.4f);
    //sprintf 会把3个数字按照格式要求转换成字符,然后把这组字符存在str数组里,成为一个字符串
    sprintf(str,"%c %d %g", 'r', 87, 5.4f);
    printf("%s \n", str);

    //scanf可以从键盘里获得多个数字并记录到存储区里
    // scanf("%c%d%g", &ch, &val, &fval);

    //sscanf可以从字符串里获得多个数字并记录到存储区里
    sscanf("p 34 7.6","%c%d%g", &ch, &val, &fval);
    printf("%c %d %g \n",ch, val, fval);

    return 0;
}

/*
output:
r 87 5.4
r 87 5.4
p 34 7.6
*/
  • 5.1 下面两个字符串相关函数需要包含stdlib.h头文件
    • atoi 函数可以把字符串开头部分整数转换成整数类型
    • atof 函数可以吧字符串开头部分的浮点数转换成双精度浮点类型
#include <stdio.h>
#include <stdlib.h>

int main() {
    int val = atoi("12sdfkasf");
    printf("%d\n", val);
    double dval = atof("34.23zfsdafasf");
    printf("%lg \n", dval);
    return 0;
}

/*
output:
12
34.23
*/
  • 6.从键盘获得字符串的方法
    • scanf 有可能出现严重错误
      • 1.会将输入空格符当做’\0’,’\0’后面的并不记录。
      • 2.存放输入的字符数组不够大了
    • fgets函数也可以从键盘得到字符串并记录到字符数组里,
      • 避免了scanf可能出现的问题
      • 如果输入内容不能充满数组就把用户最后输入的enter当做’\n’字符放进数组里
      • 如果数组放不下用户输入的内容就只获得输入的前一部分内容,把后面的一部分内容留在输入缓冲区里,如果下次再调用fgets函数,得到的将只会是上一次遗留在缓冲区的内容
      • 每次使用fgets函数从键盘得到字符串后应该删除输入缓冲区里的多余数据(删除语句应该写在分支里,确定输入缓冲区里存在多余数据的时候才应该进行删除操作,不然删除操作会卡住)
#include <stdio.h>
#include <string.h>

int main() {
    char str[10] = {0};
    printf("请输入字符串: ");
    fgets(str, 10, stdin);
    printf("%s \n", str);

    //删除输入缓冲区的内容
    //用分组来保证输入缓冲区里是有多余数据的
    //首先数组要被充满,且最后一个存储区不能是enter对应的\n,不然缓冲区还是可能没数据,程序又会卡主等待用户输入到缓冲区内容,再删缓冲区
    //数组充满的情况是:数组里有10个存储区, 有效字符是9个,最后一个放\0
    if (strlen(str) == 9 && str[8] != '\n') {
        scanf("%*[^\n]");
        scanf("%*c");
    }

    printf("请输入字符串: "); 
    fgets(str, 10, stdin);
    printf("%s \n", str);
    return 0;
}

  • 7.字符指针数组
    • 在c语言中记录多个相关字符串*
#include <stdio.h>
// #include <string.h>

int main() {
    //char * : 字符指针类型
    //声明一个字符指针数组, 第一个指针指向"abc"这个字符... 
    //编译器在编译的时候会把"abc"替换成字符'a'所在存储区的地址
    char *str[] = {"abc", "def", "ghi"};
    int num = 0;
    for(num = 0; num <= 2; num++) {
        printf("%s\n", str[num]);
    }

    return 0;
}
 /*
 output: 
abc
def
ghi
*/
    • 主函数的第二个参数就是一个字符指针数组
#include <stdio.h>
// #include <string.h>
//主函数的第一个参数是一个整数,第二个参数是一个字符指针数组。
int main(int argc, char *argv[]) {
    int num = 0;
    for (num = 0; num <= argc -1; num ++) {
        printf("%s\n", argv[num]);
    }
    return 0;
}

 /*
intput: 
./a.out abc def ghi

 output: 
abc
def
ghi

*/
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值