尧图网站设计 尧图网站设计YAOTU DESIGN
ARTICLE DETAIL

资讯详情

深耕网站设计与一线实操的经验洞察。

字符串操作学习

字符串操作学习 简介在常见的代码编写中程序员都必须要跟各种各样的字符串打交道有的需要从字符串中获取某个数据有的要将数据拼接成字符串有时又需要我们球的字符串的长度所以掌握如何处理字符串显得尤为重要一.基础操作--长度、复制、拼接、比较1.strlen--获取字符串长度(不计入\0)size_t strlen(const char *s)功能获取字符串s的长度返回值返回字符串的长度拓展size_t是无符号整型具体大小根据平台不同而变化以下代码进行测试一般为8字节size_t len strlen(hello); printf(%zu, len); //%zu是专门用于打印size_t类型的参数需要计算长度的字符串2.strcpy--复制字符串char *strcpy(char *dest, const char *src)功能将src中的字符串复制到dest中返回值dest的首地址方便调用参数dest复制后存放字符串的位置src需要复制的字符串strncpy--更安全的复制函数char *strncpy(char *dest, const char *src, size_t n)功能指定最多从src中复制n个字符到dest中返回值char *dest的首地址参数dest复制后存放字符串的位置src需要复制的字符串n最多从src中复制n个注意src长度 n --长度不足以 \0补充src长度 n --长度超出注意此时dest不是以\0结尾不是完整的字符串所以在使用strncpy是一般要自己手动在尾部写上\0示例char buf[10]; strncpy(buf, Hello,World!, sizeof(buf) - 1); buf[sizeof(buf) - 1] \0; 这里的字符串长度超出了数组长度手动加上\03.strcat--拼接字符串char *strcat(char *dest, const char *src)功能将src拼接到dest末尾覆盖dest的\0返回值dest的首地址方便调用参数dest拼接字符串的前部分拼接后的字符存放在dest中原本的dest被修改了src拼接字符串的后部分strncat--更安全的拼接函数char *strncat(char *dest, const char *src, size_t n);功能指定最多从src中取n个字符拼接到dest的末尾n dest剩下的空间并且要留出一个字节给\0从上面2个拼接函数strcat和strncat这2个拼接函数比较不好使用因为其存在的限制较大很容易出现字符串不完整的情况使用场景中有更好的替代方法--snprintf看下面第三部分4.strcmp--比较字符串int strcmp(const char *str1, const char *str2);功能按照ASCII表比较两个字符串str1和str2 非常好用返回值02个字符串完全相同0str1的同位字符 str2的同位字符0str1的同位字符 str2的同位字符参数str1 str2--需要比较的2个字符串str1 hello; str2 hello; if(strcmp(str1, str2) 0) { printf(这两个字符串相同); }二.搜素操作1.strchr--在字符串中搜索指定的字符char *strchr(const char *str, int ch);功能从str中寻找ch第一次出现的位置返回值找到返回ch在str中第一次出现的位置失败NULL参数str被寻找的字符串ch需要寻找的字符#include stdio.h #include string.h int main(void) { const char *str hello; char ch l; char *p_ch strchr(str, ch); printf(找到的字符为%c\n, *p_ch); printf(l出现在str的第:%ld位, p_ch - str); return 0; } /*运行结果:3*/2.strrchr--从字符串的末尾开始寻找指定的字符char *strrchr(const char *s, int c);#include stdio.h #include string.h int main(void) { const char *str hello; char ch l; char *p_ch strrchr(str, ch); printf(找到的字符为%c\n, *p_ch); printf(l出现在str的第:%ld位, p_ch - str); return 0; } /*运行结果:4*/3.strstr--在字符串中搜索指定的子字符串char *strstr(const char *haystack, const char *needle);功能从haystack中寻找needle第一次出现的地方返回值找到返回needle在haystack中第一次出现的位置失败NULL参数haystack被寻找的字符串needle需要寻找的子字符串#include stdio.h #include string.h int main(void) { const char *haystack hello; const char *str llo; char *p strstr(haystack, str); printf(%s\n, p); return 0; } 运行结果llo三.分割与拼接操作1.sscanf--按指定格式获取字符串int sscanf(const char *str, const char *format, ...)功能从str中按照指定格式读出数据类比scanf但是不是从屏幕中读取而是字符串返回值成功读取并赋值的参数个数参数str目标字符串format变参跟scanf的输入相同int main(void) { const char *str 1998-helloworld-18.1; int year; float num; char strs[20] {0}; sscanf(str,%d-%[^-]-%f, year, strs, num); printf(%d, %s, %f\n, year, strs, num); return 0; } 运行结果1998, helloworld, 18.100000 2.strtok--按指定的分隔符获取子字符串char *strtok(char *str, const char *delim);功能根据delim的字符分割str返回值返回每次切割成功后的子字符串参数str需要切割的字符串delim切割的标志字符串可以有多个切割标志如 \.有三个 仅空格一个#include stdio.h #include string.h int main(void) { char str[50] 1998-hello world-18.1; char *tmp strtok(str, - .); while(tmp ! NULL) { printf(%s\n, tmp); tmp strtok(NULL, - .); } return 0; } 运行结果:1998 hello world 18 1 代码含义:以 - .为分割注意1.strtok会修改原来的字符串str所以str必须是可修改的const 或者 char *str都不行2.在第一次切割的时候需要传入str的地址后续的切割需要改为NULL,不然会一直输出相同的数据3.sprintf--按指定的格式格式化拼接字符串#include stdio.h int sprintf(char *str, const char *format, ...);功能按照指定格式将字符串存入str中返回值成功写入的字符个数不包含\0参数str存放格式化后的字符串format格式化字符串等同于printf的使用但是格式化后的数据不打印在屏幕上而是存到数组中#include stdio.h #include string.h int main(void) { char str[50] {0}; int y 2026, m 7, d 21; sprintf(str, %d-%d-%d, y, m, d); printf(%s\n, str); return 0; } 运行结果2026-7-21能用于将不同类型的数据格式化后转为字符串非常好用四.内存操作函数为什么要提到内存操作函数内存操作函数能够更灵活的对数据进行操作上述的字符串函数只局限在字符串内以\0作为结束条件而内存操作函数能够对任意类型的数据进行操作1.memcpy--复制指定的字节个数到指定的内存#include string.h void *memcpy(void *dest, const void *src, size_t n);功能将n个src中的数据复制到dest中注意这里的都是void*说明支持任意相同类型的数据返回值dest的内存地址参数dest目标位置的地址src源数据的地址n需要复制的字节数这类内存相关的函数常用于数组字符串结构体截取部分数据#include stdio.h #include string.h struct Student{ char name[20]; int grade; int phone; int code; }std; int main(void) { struct Student std1 {xiaoming, 99, 123456, 1}; struct Student std2 {0}; memcpy(std2, std1, sizeof(struct Student)); //注意这的参数是地址 printf(%s, %d, %d, %d\n,std2.name, std2.grade, std2.phone, std2.code); return 0; } 运行结果xiaoming, 99, 123456, 12.memset--向指定内存写入指个数的数据void *memset(void *s, int c, size_t n);功能向指定内存写入指定个数的数据返回值s的内存首地址参数s需要填充的地址c要填充的值以int传递但是会转为unsigned charn要填充的字节数#include stdio.h #include string.h int main(void) { int buf[5] {8,5,3,2,1}; for(int i 0; i sizeof(buf) / sizeof(int); i) printf(buf[%d]:%d , i, buf[i]); printf(\n); memset(buf, 0, sizeof(buf)); for(int i 0; i sizeof(buf) / sizeof(int); i) printf(buf[%d]:%d , i, buf[i]); printf(\n); } 运行结果 buf[0]:8 buf[1]:5 buf[2]:3 buf[3]:2 buf[4]:1 buf[0]:0 buf[1]:0 buf[2]:0 buf[3]:0 buf[4]:0 五.其他操作函数1.atoi--字符串转intint atoi(const char *str)功能将字符串转为整数返回值成功返回转换后的整数值失败0参数str需要转化的字符串#include stdio.h #include stdlib.h int main(void) { char str[] 119; //直接转 char str1[] 122;//支持跳过空格 char str2[] 345; //支持识别正号 char str3[] -555; //支持识别负号 char str4[] 245abc; //遇到非数字停止 printf(%d\n,atoi(str)); printf(%d\n,atoi(str1)); printf(%d\n,atoi(str2)); printf(%d\n,atoi(str3)); printf(%d\n,atoi(str4)); return 0; } 运行结果:119 122 345 -555 245 注意atoi无法区分错误和0当错误时会返回02.atol--字符串转long#include stdlib.h long atol(const char *str);功能将字符串转为long型返回值成功返回转换后的long值失败0参数str需要转化的字符串#include stdio.h #include stdlib.h int main() { char str1[] 123456789; char str2[] -987654321; char str3[] 0; long num1 atol(str1); long num2 atol(str2); long num3 atol(str3); printf(%ld\n, num1); // 输出: 123456789 printf(%ld\n, num2); // 输出: -987654321 printf(%ld\n, num3); // 输出: 0 return 0; } 运行结果123456789 -987654321 0 与atoi对比对比项atoiatol返回值类型intlong取值范围32位-21亿 ~ 21亿64位-922亿亿 ~ 922亿亿错误处理返回 0返回 0适用场景小数字大数字3.atof--字符串转double#include stdlib.h double atof(const char *str)功能将字符串转为double型返回值成功返回转换后的double值失败0.0参数str需要转化的字符串#include stdio.h #include stdlib.h int main() { printf(%f\n, atof( 3.14)); // 3.140000忽略前导空格 printf(%f\n, atof(6.28)); // 6.280000支持正号 printf(%f\n, atof(-9.87)); // -9.870000支持负号 printf(%f\n, atof(.123)); // 0.123000无整数部分 printf(%f\n, atof(123.)); // 123.000000无小数部分 printf(%f\n, atof(1.23e-4)); // 0.000123科学计数法 printf(%f\n, atof(2.5abc)); // 2.500000遇到非数字停止 printf(%f\n, atof(abc)); // 0.000000无法转换 printf(%f\n, atof()); // 0.000000空字符串 printf(%f\n, atof( )); // 0.000000只有空格 printf(%f\n, atof( 1 2)); // 0.000000两个数字之间空格 return 0; } 运行结果 3.140000 6.280000 -9.870000 0.123000 123.000000 0.000123 2.500000 0.000000 0.000000 0.000000 1.000000 可以看到atof可以转化小数也可以识别科学计数法也能跳过空格情况处理方式示例前导空白字符跳过空格、制表符等 123→123.0正负号支持和--45.6→-45.6整数部分转换123→123.0小数点识别小数部分3.14→3.14科学计数法支持e或E1e3→1000.0非数字字符遇到即停止12.5abc→12.5无有效数字返回0.0abc→0.0
返回列表