c语言字符串

1.字符串:以0结尾的一串字符

  0和'\0'是一样的,但是和'0'不一样,0用来标志字符串的结束,不是字符串的一部分,计算字符串的长度的时候,不包括这个0,字符串以数组的形式存在,以数组或指针的方式访问

  char[]={'H','e','l','l','o','w'};  //是字符数组,不是字符串

  char[]={'H','e','l','l','o','w','\0'};  //是字符数组,是字符串

  字符串声明的方式:

    char *str="Hello";

    char a[]="Hello";

    char line[10]="Hello";

    char[]={'H','e','l','l','o','w','\0'};

2.字符串常量:

  类似于“Hello”这种用双引号包围的字符序列

  编译器会将字符串常量变成一个字符数组存放在某处

  不能使用运算符对字符串进行操作,因为他的本质是一个字符数组

 

3.可修改和不可修改字符串

  char *str="Hello"  //不可修改,在这里“Hello”作为一个字符串常量,会被存放在代码段,代码段的内容只可以读,不可写,如果使用str[0]='B'来修改字符串,将会报错

  char str[]="Hello"  //这是一个字符串数组,存放在堆栈区,跟一般的变量一样,因此可以修改。编译器在编译这行代码的时候,仍然会把“Hello”存放在代码段,但是执行这一句的时候,会把代码段的"Hello"拷贝到堆栈区

 

4.什么时候用char str[]和char *str

  字符数组的时候使用str[]

  函数参数的时候可以使用*str,这个时候未必指向代码段的字符串地址,可能是堆栈区的字符串地址。malloc动态分配内存的时候用*str.

 

5.字符串的输入输出

  char *s="title"

  char *t=s  //这时t指向了和s同样的在代码段的字符串的地址,并没有赋值成一个新的字符串

  scanf("%s",string)    //向字符数组string里面输入字符串,遇到空格、table、换行的时候停止读入,假如后续再读一个字符串,这个空格、tab、换行也不会被读入下一个字符串。假如string的长度为8,而读入了超过7个字符还没有碰到空格、tab或者换行,程序可能报错。

  scanf("%7s",string)  //string最多读入7个字符,不足7个就遇到空格、tab、换行时直接结束

  printf("%s",string)    //输出字符串

  常见错误:

    char *string;

    printf("%s",string);      //string 没有初始化,可能会出错

 

6.空字符串

  char s[100]="";  //长度为100的空字符串 ,s[0]是‘\0’

  char s[]="";    //长度为1的空字符串 ,s[0]是‘\0’

 

7.字符串数组

  char a[][10]={"hello","world"}    //连续的20个char长度的地址,注意数组的第二维必须声明长度,否则编译报错

  char *a[]    //一个字符串指针数组,每一个元素都是一个指向字符串的指针

 

8.getchar()和putchar()

  int getchar()  从键盘读入一个字符,返回一个int类型,假如读入到末尾,返回的是预定义值EOF(-1).

  int putchar(int a)  //接受一个字符的ASCII码,将这个字符输入到命令行。

9.string.h库文件

  string.h提供了很多处理字符串的函数

    -strlen    返回 字符串的长度,不包含'\0',sizeof返回的长度包含'\0'

int strlen(const char* s){
    int idx=0;
    while(s[idx]!='\0')
        idx++;
    return idx;
}

 

    -strcmp   比较字符串

int strcmp(const char* s1,const char* s2){
    while(*s1==*s2&&*s1!='\0'){
        s1++;
        s2++;
    }
    return  *s1-*s2;
}

 

    -strcpy  字符串复制

char *strcpy(char *dst,const char *src){
    int idx=0;
    while(src[idx]){
        dst[idx]=[src[idx]];
        idx++;
    }
    dst[idx]='\0';
    return dst;
}

 

    -strcat  字符串拼接

  以上3个函数都不安全,可能存在越界的风险,从函数的实现可以看出这些字符串的处理是直到遇到‘\0’才结束的,因此有越界风险。

  解决方法:使用以下安全函数:(注意第一个参数是目的,第二个参数是源)

    char * strncpy(char *restrict dst,const char *restrict src,size_n t)    将src字符数组中前n个字符复制到dst中。//resitrct关键字表示两个变量不指向同一个数据(也不能重叠(例如Hello,dst指向H的地址,src指向l的地址就是重叠))。

    char * strncat(char *restrict dst,const char *restrict src,size_n t)    将src字符数组中前n个字符复制到dst中。

    char * strncmp(char *dst,const char *src,size_n t)          只比较src和dst中的前n个字符

 

 

    -strchr(const char*s,int c)  从s字符数组中从左往右找c,找到之后返回字符c对应的地址

    -strrchr(const char*s,int c)  从s字符数组中从右往左找c,找到之后返回字符c对应的地址

    -strstr(const char *s1,const char *s2)  从s1中找字符串s2,返回找到之后的首地址

    -strcasestr(const char *s1,const char *s2)  从s1中找字符串s2,返回找到之后的首地址,不区分大小写地找

posted @ 2020-07-31 09:58  9761滴  阅读(229)  评论(0编辑  收藏  举报