• C复习-字符串+字符+字节


    参考: 里科《C和指针》


    长度strlen

    库函数strlen返回的是size_t(stddef.h中定义,是一个无符号整数)。如果需要跟int做比较、加减,需要加类型转换,否则结果可能是错的

    if( strlen(x) >= strlen(y) )
    if( strlen(x) - strlen(y) >= 0 ) // size_t是无符号数,相减结果也是size_t,肯定是永远非负
    if( strlen(x) - 10 >= 0 ) // 这个也会永远true
    
    #include 
    #include 
    
    		char s[] = "test";
        cout << typeid(strlen(s) - 10).name() << endl; // unsigned __int64
        cout << strlen(s) - 10 << endl; // 18446744073709551610
        cout << typeid(strlen(s)).name() << endl; // unsigned __int64
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11

    字符串复制strcpy

    复制字符串使用的strcpy,要求目标字符数组的空间必须足够容纳待复制的字符串。strcpy不会检查目标字符数组的长度,所以复制过长的字符串时,会越界改写,报错。

    char *strcpy(char *dst, char const *src);
    
    • 1

    字符串连接strcat

    就是将src拷贝到dst末尾。同样需要程序员保证空间充足

    char *strcat(char *dst, char const *src);
    
    • 1

    strcpy/strcat返回的是第一个参数的拷贝,即指向目标字符数组的指针。不过返回值一般都被忽略。

    字符串比较strcmp

    逐个字符比较,直到发现不匹配,此时如果那个字符比较小(字符集中的序数),则认为那个字符串比较小。使用strcmp,如果s1返回负值,大于返回正值,等于返回0。

    int strcmp(char const *s1, char const *s2);
    
    • 1

    限定复制、连接和比较的长度strnXXX

    strncpy、strncat和strncmp多加一个形参size_t len,用来限定操作范围。

    strncpy:如果src的长度小于len,dst会用NUL填充到len长度;否则只复制len个,此时需要手动加\0,因为不会自动以NUL结尾

    strncat:添加完后自动添加NUL

    字符串查找单个字符

    // 以下两个函数区分大小写
    // 查找第一次出现的位置,找到后返回指针;找不到返回NULL
    // char *ans = strchr(string, 'h');
    char *strchr(char const *str, int ch);
    // 从右边开始查找
    char *strrchr(char const *str, int ch);
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6

    查找一组字符

    只要其中一个字符出现即返回指针。区分大小写

    char *strpbrk(char const *str, char const *group);
    
    char string[20] = "Hello there";
    char *ans = strpbrk(string, "aeiou");
    // ans = string + 1,因为e出现了
    
    • 1
    • 2
    • 3
    • 4
    • 5

    查找一个子串

    返回指针,指向s2在s1中第一次出现的位置。如果没有返回NULL。如果s2是空串,返回s1

    char *strstr(char const *s1, char const *s2);
    
    • 1

    查找一个字符串前缀

    size_t strspn(char const *str, char const *group);
    // 这个c指的complement,指遇到匹配group的就停止
    size_t strcspn(char const *str, char const *group); 
    
    int len1, len2;
    char buffer[] = "25,142,330,Smith,J,239-4123";
    len1 = strspn(buffer, "0123456789"); // 2,因为buffer[2]=',',不匹配了
    len2 = strspn(buffer, ",0123456789"); // 11,因为buffer[11]='S',不再匹配
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8

    查找标记token

    // 会修改原字符串,因为找到下一个标记时会给它以NUL结尾,再返回指向这个标记的指针
    // 如果str是NULL, 就从上一次查找位置之后继续查找
    char *strtok(char *str, char const *sep);
    
    void
    print_tokens(char* line) 
    {
        static char whitespace[] = " \t\f\r\v\n";
        char* token;
        for (token = strtok(line, whitespace); token != NULL;
            token = strtok(NULL, whitespace))
            printf("Next is %s\n", token);
    }
    
    int main()
    {
        char s[] = " tes\tt"; 
        print_tokens(s);
        // Next is tes
        // Next is t
        return 0;
    }
    
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23

    如果vs报错:‘strtok’: This function or variable may be unsafe. Consider using strtok_s instead. To disable deprecation, use _CRT_SECURE_NO_WARNINGS

    去调试器的属性页-C/C+±预处理器-预处理器定义,编辑,增加_CRT_SECURE_NO_WARNINGS

    同时,因为strtok保存了局部状态信息,所以不能同时解析两个字符串,因此,如果for循环的循环体中调用了一个在内部调用strtok的函数,上面的代码会失效

    字符分类

    iscntrl // 任何控制字符
    isspace // 空格 换页\f 换行\n 回车\r 制表\t 垂直制表\v
    isdigit // 0-9,十进制
    isxdigit // 0-9+a-f+A-F十六进制
    islower //
    isupper // 最好不要用if(ch >='A' && ch <='Z')判断大小写,因为有的字符集不正确
    isalpha // a~z+A~Z
    isalnum // 字母+数字
    ispunct //标点符号,任何不属于数字和字母的图形字符(可打印符号)
    isgraph // 任何图形字符
    isprint // 任何可打印字符,包括图形字符和空白字符
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11

    字符转换

    int tolower(int ch);
    int toupper(int ch);
    
    • 1
    • 2

    内存操作

    因为字符串函数处理不了内部有NUL的情况,但是下面可以。其中Length指的是字节,所以如果不是单字节的数据,需要使用sizeof

    // 复制,但是dst和src重叠的结果未知
    void *memcpy(void *dst, void const *src, size_t length);
    // 如果是复制整型数组,可以把length写成sizeof(src)
    // 如果只是复制部分,length=count * sizeof(src[0])
    
    // 复制,dst和src可以重叠,比memcpy慢
    void *memmove(void *dst, void const *src, size_t length);
    void *memcmp(void const *a, void const *b, size_t length);
    
    // 查找ch第一次出现的位置,共查找length个字节
    void *memchr(void const *a, int ch, size_t length);
    
    // 从a开始的length个字节设置为ch
    void *memset(void *a, int ch, size_t length);
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
  • 相关阅读:
    时钟轮在 RPC 中的应用
    攻防世界WEB练习-favorite_number
    使用 pyspark 进行 Classification 的简单例子
    基于Python的旅游景点推荐系统设计与实现(源码+数据库+讲解)
    python多任务、面向对象、命令行启动动态绑定端口号静态web服务器代码实现
    识别“数据陷阱”,发现数据的可疑之处
    树链剖分基础入门 -- 强大的树上操纵数据结构
    如何在 Cypress 测试中通过 URL 下载文件?
    基于FPGA MIPS CPU设计学习(1)
    生活无趣感的成因与破解之道
  • 原文地址:https://blog.csdn.net/pxy7896/article/details/134249263