美文网首页
04-2.C(字符串和函数)

04-2.C(字符串和函数)

作者: 任振铭 | 来源:发表于2018-04-30 10:19 被阅读16次

    01.scanf

    1)scanf将回车空格都当作字符串结束的标志
    2)以回车键作为输入完成的标识,但是回车键本身不会作为字符串的一部分
    3)存在安全问题,加入用户在键盘输入的内容超过scanf参数中的数组长度,就会内存溢出,发生奔溃,这也就是微软在使用scanf函数时需要加上顶部#define

    
    #define _CRT_SECURE_NO_WARNINGS
    #include <stdio.h>
    
    int main() {
        char buf[100] = { 0 };
        printf("请输入字符串buf:");
        scanf("%s",buf);
        printf("buf=%s\n", buf);
    
        char temp[100] = { 0 };
        printf("请输入字符串temp:");
        scanf("%s", temp);
        printf("buf=%s\n", temp);
    
        //scanf不做越界检查,所以是不安全的,
        //如果输入的数量超过了数组长度,就会发生异常
        char str[10] = { 0 };
        printf("请输入字符串str:");
        scanf("%s", str);
        printf("buf=%s\n", str);
    
        system("pause");
    }
    

    控制台:

    请输入字符串buf:hello
    buf=hello
    请输入字符串temp:world
    buf=world
    请输入字符串str:haha
    buf=haha
    请按任意键继续. . .
    

    加入我这样输入,一次性输入三个单词,以空格隔开,看打印的情况,

    请输入字符串buf:hello world haha
    buf=hello
    请输入字符串temp:buf=world
    请输入字符串str:buf=haha
    请按任意键继续. . .
    

    我们可以分析一下scanf的工作原理,在键盘上输入hello world haha
    回车之后,会将hello world haha\n放入缓冲区(内存),这时运行
    到scanf函数的时候,会去缓冲区中检查,看有没有输入的内容,如
    果没有则等待输入,如果有,则取出一个,以空格为标识,取出了
    第一个hello,然后第二个scanf同样道理,取出第二个单词world,第
    三个取出最后一个

    sscanf(按照指定的格式提取内容)

    scanf可以理解为按照指定格式(以空格分隔的格式),从标准输入中提取内容,那么sscanf就是按照指定格式(不再局限于空格分隔),从指定的内容中,一般是字符串中,提取内容,可以看到下面的程序最后一次提取是没有成功的,提取字符串用逗号分割会有问题,用空格可以,提取整型数据用逗号可以实现,用空格也可以实现

    
    #define _CRT_SECURE_NO_WARNINGS
    #include <stdio.h>
    #include <string.h>
    
    int main() {
        char buf[] = "1 2 3";
        int a, b, c;
        //从buf中指定的格式提取内容
        sscanf(buf, "%d %d %d", &a, &b, &c);
        printf("a = %d,b=%d,c=%d",a, b, c);
        printf("\n---------------------------------------------\n");
        //提取整型变量是最方便的
        char str[] = "a=1,b=2,c=3";
        a = 0;
        b = 0;
        c = 0;
        sscanf(str, "a=%d,b=%d,c=%d", &a, &b, &c);
        printf("a = %d,b=%d,c=%d", a, b, c);
        printf("\n---------------------------------------------\n");
        char str2[] = "1;2;3";
        a = 0;
        b = 0;
        c = 0;
        sscanf(str2, "%d;%d;%d", &a, &b, &c);
        printf("a = %d,b=%d,c=%d", a, b, c);
        printf("\n---------------------------------------------\n");
        char temp[] = "abc ren 434";
        char m[10], n[10], o[10];
        sscanf(temp, "%s %s %s", m, n, o);
        printf("m = %s,n=%s,o=%s", m, n, o);
        printf("\n---------------------------------------------\n");
        char temp2[] = "abc,ren,434";
        char m2[10], n2[10], o2[10];
        sscanf(temp2, "%s,%s,%s", m2, n2, o2);
        printf("m = %s,n=%s,o=%s", m2, n2, o2);
        system("pause");
    }
    
    打印:
    a = 1,b=2,c=3
    ---------------------------------------------
    a = 1,b=2,c=3
    ---------------------------------------------
    a = 1,b=2,c=3
    ---------------------------------------------
    m = abc,n=ren,o=434
    ---------------------------------------------
    m = abc,ren,434,n=烫烫烫烫烫烫烫烫烫烫abc,ren,434,o=烫烫烫烫烫烫烫烫烫烫烫烫烫烫烫烫烫烫烫烫abc,ren,434请按任意键继续. . .
    

    02.gets(已经不建议使用了)

    #include <stdio.h>
    char *gets(char *s)
    

    从标准输入读取字符,并保存到s(一般是个数组,s是数组首地址)指定的内存空间,知道出现换行符或读取到文件结尾为止,和scanf不同之处,在于可以读取空格,有数组越界的风险,比如输入的大于数组的极限

    #define _CRT_SECURE_NO_WARNINGS
    #include <stdio.h>
    
    int main() {
        char buf[10];
        gets(buf);
        printf("%s\n", buf);
        system("pause");
    }
    

    02.fgets(可以指定读取的大小,是安全的)

    #include <stdio.h>
    char *fgets(char *s,int size,FILE *stream);
    

    从stream指定的文件流读入字符,保存到s所指定的内存空间,直到出现换行符都到文件结尾或是已读了size-1个字符为止,最后会自动加上字符'\0'作为字符串结束标志

    #include <stdio.h>
    
    int main() {
        char buf[10];
            //从stdin,也就是键盘输入流读取内容,如果输入内容大
            //于sizeof(buf)-1,只读取sizeof(buf),注意它会把换行            符也读
            //进去
        fgets(buf, sizeof(buf), stdin);
        printf("buf = %s\n", buf);
        system("pause");
    }
    打印:
    abcdefghijklmn
    buf = abcdefghi
    请按任意键继续. . .
    

    03.puts(字符串输出到屏幕,类似printf)

    include <stdio.h>
    int puts(const char *)
    

    标准设备输出字符串,在输出完成后,自动输出一个'\n',换行,注意字符串本身没有变化

    #include <stdio.h>
    
    int main() {
        char buf[] = "hello";
        //打印字符串buf,可以证明这个字符串本身是没有换行的
        printf("buf = %s", buf);
        //把buf内容输出到屏幕,自动在屏幕加换行,在屏幕加,字符串本身没变化
        puts(buf);
        //再次打印字符串,证明字符串本身没有变化
        printf("buf = %s", buf);
        system("pause");
    }
    打印
    buf = hellohello
    buf = hello请按任意键继续. . .
    

    04.fputs(是puts的文件操作版本,但不会输出换行)

    #include <stdio.h>
    int fputs(const char *str,FILE *stream)
    

    把指定内容输出到一个文件流中,puts是输出到屏幕,和puts区别在于它可以指定输出到哪个文件流,这个文件流也包括屏幕,只要将stream指定为stdout即可,并且不会在输出内容上加换行符

    #include <stdio.h>
    
    int main() {
        char buf[] = "hello";
        fputs(buf, stdout);
        system("pause");
    }
    输出:
    hello请按任意键继续. . .(没有换行)
    

    05.strlen

    #include<string.h>
    size_t strlen (const char *s)
    

    计算指定字符串s的长度,不包含字符串结束符'\0'(size_t为unsigned int 类型)

    #include <stdio.h>
    #include <string.h>
    
    int main() {
        char buf[] = "hello";
        //strlen是从首元素开始,到结束符为止的长度,结束符不算
        //到\0为止,所以如果手动加上了\0,比如he\0llo的strlen结果就是2
        int len = strlen(buf);
        printf("len = %d\n",len);
        printf("sizeof(buf) = %d\n", sizeof(buf));
    
        char buf2[] = "\0hello";
        len = strlen(buf2);
        printf("len2 = %d\n", len);
        //sizeof测量的是数据类型的长度,不会因为结束符而提前结束,他的计算结果
        //包括结束符,所以buf2的sizeof结果是7,因为最后还有一个结束符
        printf("sizeof(buf2) = %d\n", sizeof(buf2));
        system("pause");
    }
    打印:
    len = 5
    sizeof(buf) = 6
    len2 = 0
    sizeof(buf2) = 7
    请按任意键继续. . .
    

    6.strcpy

    #include <string.h>
    char *strcpy (char *dest,const char *src);
    

    把src所指向的字符串复制到dest所指向的空间中,'\0也会拷贝过去',成功则返回dest字符的首地址,如果dest的空间不够大可能会溢出,当它复制的时候会从首地址开始,到\0结束,所以第二个打印只有一个hello输出

    //因为不是安全的,所以要加上这个
    #define _CRT_SECURE_NO_WARNINGS
    #include <stdio.h>
    #include <string.h>
    
    int main() {
        char src[100] = "hello world";
        char dest[100];
        strcpy(dest,src);
        printf("dest = %s\n", dest);
    
        char src2[100] = "hello\0 world";
        char dest2[100];
        strcpy(dest2, src2);
        printf("dest2 = %s\n", dest2);
        system("pause");
    }
    
    打印
    dest = hello world
    dest2 = hello
    请按任意键继续. . .
    
    

    7.strncpy(没有溢出的隐患,安全)

    这个也会以\0结束,

    #include <stdio.h>
    #include <string.h>
    
    int main() {
        char src[100] = "hello world";
        char dest[100];
            //拷贝一个字符到dest
        strncpy(dest,src,1);
        printf("dest = %s\n", dest);
        system("pause");
    }
    

    strcmp

    #include <string.h>
    char *strcmp(const char *s1,const char *s2);
    

    比较s1和s2的大小,比较的是字符ASCII码大小,0表示相等,>0表示大于,小于0表示小于

    #include <stdio.h>
    #include <string.h>
    
    int main() {
        char s1[] = "abc";
        char s2[] = "abcd";
        int flag = strcmp(s1, s2);
        if (flag == 0) {
            printf("相等");
        }
        else if (flag > 0)
        {
            printf("s1 > s2");
    
        }
        else if (flag < 0)
        {
            printf("s1 < s2");
    
        }
        system("pause");
    }
    
    打印结果:s1<s2
    

    strcnmp (可以指定比较的字符范围)

    #include <stdio.h>
    #include <string.h>
    
    int main() {
        char s1[] = "abc";
        char s2[] = "abcdef";
        int flag = strncmp(s1, s2,3);
        if (flag == 0) {
            printf("相等");
        }
        else if (flag > 0)
        {
            printf("s1 > s2");
    
        }
        else if (flag < 0)
        {
            printf("s1 < s2");
    
        }
        system("pause");
    }
    
    打印结果:相等
    

    strcat 字符串追加

    #define _CRT_SECURE_NO_WARNINGS  //不安全
    #include <stdio.h>
    #include <string.h>
    
    int main() {
        char s1[] = "abc";
        char s2[] = " defg";
        strcat(s1, s2);
        printf("%s\n",s1);
        system("pause");
    }
    
    abc defg
    请按任意键继续. . .
    

    strncat 指定追加字符串的长度(也是不安全的,strncat_s是安全的)

    严重性 代码 说明 项目 文件 行 禁止显示状态
    错误 C4996 'strncat': This function or variable may be unsafe. Consider using strncat_s instead. To disable deprecation, use _CRT_SECURE_NO_WARNINGS. See online help for details. 函数 c:\users\renzhenming\documents\visual studio 2015\projects\函数\函数\1.c 9

    #define _CRT_SECURE_NO_WARNINGS
    #include <stdio.h>
    #include <string.h>
    
    int main() {
        char s1[] = "abc";
        char s2[] = " defg";
        strncat(s1, s2,strlen(" def"));
        printf("%s\n",s1);
        system("pause");
    }
    
    打印:abc def
    

    sprintf 格式化字符串

    严重性 代码 说明 项目 文件 行 禁止显示状态
    错误 C4996 'sprintf': This function or variable may be unsafe. Consider using sprintf_s instead. To disable deprecation, use _CRT_SECURE_NO_WARNINGS. See online help for details. 函数 c:\users\renzhenming\documents\visual studio 2015\projects\函数\函数\1.c 16

    
    #define _CRT_SECURE_NO_WARNINGS
    #include <stdio.h>
    #include <string.h>
    
    int main() {
        int a = 10;
        char c = 'd';
        char buf[] = "hello";
    
        //格式化一个字符串,把这个字符串输出到屏幕
        printf("a = %d, ch = %c , buf = %s \n",a,c,buf);
    
        //格式化一个字符串,把这个字符串保存到指定的数组
        char dest[100];
        sprintf(dest, "a = %d, ch = %c , buf = %s \n", a, c, buf);
    
        printf("%s\n",dest);
            system("pause");
    }
    
    
    a = 10, ch = d , buf = hello
    a = 10, ch = d , buf = hello
    
    请按任意键继续. . .
    

    strchr(在字符串s中查找字母c出现的位置)

    #include <string.h>
    char *strchr(const char *s ,int c);
    
    #include <stdio.h>
    #include <string.h>
    
    int main() {
        char buf[] = "abddddeee";
        //在buf中查询字符d,如果找到,返回d所在位置的地址,如果打印p
        //将得到从d所在位置开始到字符串结束的那个字符串
        char *p = strchr(buf, 'e');
        if (p == NULL) {
            printf("查询失败\n");
        }
        else {
            printf("p = %s\n",p);
        }
        system("pause");
    }
    

    strstr(在字符串haystack中查找needle出现的位置)

    #include<string.h>
    char *strstr(const char *haystack,const char *needle);
    
    #include <stdio.h>
    #include <string.h>
    
    int main() {
        char buf[] = "abddddeee";
        //在buf中查询字符串,如果找到,返回d所在位置的地址,如果打印p
        //将得到从d所在位置开始到字符串结束的那个字符串
        char *p = strstr(buf, 'de');
        if (p == NULL) {
            printf("查询失败\n");
        }
        else {
            printf("p = %s\n",p);
        }
        system("pause");
    }
    

    strtok字符串切割

    #include <string.h>
    char *strtok(char *str ,const char *delim)
    

    用来将字符串切割成一个个片段,当strtok再参数s的字符串中发现参数delim中包含的分割字符时,则会将该字符改为\0字符,当连续出现多个时只替换第一个\0,这个函数是不安全的要加声明

    #define _CRT_SECURE_NO_WARNINGS
    #include <stdio.h>
    #include <string.h>
    
    int main() {
        char buf[] = "hello,world,tomorrow";
        //第一次调用,第一个参数写源字符串,第二个参数写切割字符
        //返回值就是切割后的字符串,在匹配切割字符的地方,换成结束符,
        char *p = strtok(buf,",");
        printf("p=%s\n", p);
        //使用strtok会破环原来的字符串结构,这时打印字符串得到的是切割后的
        printf("buf=%s\n", buf);
        printf("buf[5]=%d\n", buf[5]);
        system("pause");
    }
    
    p=hello
    buf=hello
    buf[5]=0
    请按任意键继续. .
    

    第二次切割

    #define _CRT_SECURE_NO_WARNINGS
    #include <stdio.h>
    #include <string.h>
    
    int main() {
        char buf[] = "hello,world,tomorrow";
        //如果没有切割成功,返回NULL
        char *p = strtok(buf,",");
        printf("p1=%s\n", p);
        //第二次调用,第一个参数写NULL
        p = strtok(NULL, ",");
        printf("p2=%s\n", p);
        system("pause");
    }
    

    循环切割

    #define _CRT_SECURE_NO_WARNINGS
    #include <stdio.h>
    #include <string.h>
    
    int main() {
        char buf[] = "hello,world,tomorrow";
        //如果没有切割成功,返回NULL
        char *p = strtok(buf,",");
        while (p != NULL) {
            printf("p = %s\n", p);
            p = strtok(NULL, ",");
        }
        system("pause");
    }
    

    atoi

    #include <stdlib.h>
    int atoi(const char *ch);
    

    atoi会扫描字符串ch,跳过前面的空格符,直到遇到正负号或数字才开始做转换(转换为数字),遇到非数字或字符串结束符\0才结束转换,并将结果返回

    类似的函数有:
    atof:把小数形式的字符串转换为float类型
    atol:把一个字符串转化为long类型

    #include <stdio.h>
    #include <string.h>
    
    int main() {
        char buf[] = "-10";
        printf("num = %d\n",atoi(buf));
        system("pause");
    }
    

    相关文章

      网友评论

          本文标题:04-2.C(字符串和函数)

          本文链接:https://www.haomeiwen.com/subject/jguwlftx.html