【C 字符串】02 常用字符串函数(命令行参数) | 您所在的位置:网站首页 › strcmp函数在哪个数据库 › 【C 字符串】02 常用字符串函数(命令行参数) |
Navigator
一、strlen()函数—统计长度二、strcat()函数—拼接三、strncat()函数—strcat()的升级四、strcmp()和strncmp()—比较五、strcpy()和strncpy()—拷贝六、sprintf()函数—合并多个字符串七、其他可能用到的字符串函数八、ctype.h中的字符函数九、把字符串转换为数字十、命令行参数十一、练习—字符串排序附录:
C库提供了多个处理字符串的函数,ANSI C把这些函数的原型放在string.h头文件中。其中最常用的函数有strlen()、strcat()、strcmp()、strncmp()、strcpy()和strncpy()。另外,还有sprintf()函数,其原型在stdio.h头文件中。 本文末尾附有:string.h系列函数的完整列表。 一、strlen()函数—统计长度strlen()函数用于统计字符串的长度,但是不把字符串结尾字符 ‘\0’ 计算在内。(‘\0’ 实际上是占用存储空间的)。 (1)当字符串用数组形式定义,且根据初始化字符串分配存储空间时: strlen()函数计算字符串除了 ‘\0’ 字符的长度;sizeof()函数计算字符串实际占用内存的字节数,包括结尾的 ‘\0’ ;如果字符串使用指针形式定义:strlen()函数不变,sizeof()函数计算的是这个指针变量本身的大小(而不是它指向的那个字符串的大小),64位系统是8个字节;对于字符数组:两者都可以计算字符数组的元素个数,且相等(因为字符数组没有’\0’ 结束符)。(2)当字符串用数组形式定义,且指定长度时: strlen()函数用法不变;.直接使用sizeof()函数,返回的值与指定数组大小的值相同,因为程序根据指定的值分配内存,而不管你的字符串是否填满了这个空间。使用 sizeof(arr)/sizeof(char) 则可以获得该字符串实际占用的空间大小(包括’\0’)。总之,两者都可以计算出字符串中字符的个数(包括空格、换行等不可见字符)。但是sizeof()函数的结果比strlen()多1(即多了’\0’字符串结束符,实际占用1个字节内存),具体看你怎么用了。 示例: void strlen_test() { char s1[] = "I am dog."; char* s2 = "I am dog."; char s3[] = {'H','e','l','l','0',' '}; char s4[20] = "Hello, C."; printf("%zd\n",strlen(s1)); printf("%zd\n", sizeof(s1)); printf("%zd\n", strlen(s2)); printf("%zd\n", sizeof(s2)); printf("%zd\n", strlen(s3)); printf("%zd\n", sizeof(s3)); printf("%zd\n", strlen(s4)); printf("%zd\n", sizeof(s4)); printf("%zd\n", sizeof(s1)/sizeof(char)); }输出: 9 10 9 8 6 6 9 20 10 二、strcat()函数—拼接strcat()(用于拼接字符串)函数接受两个字符串作为参数。该函数把第2个字符串的备份附加在第1个字符串末尾,并把拼接后形成的新字符串作为第1个字符串,第2个字符串不变。strcat()函数的类型是char *(即,指向char的指针)。strcat()函数返回第1个参数,即拼接第2个字符串后的第1个字符串的地址。 注意: 创建字符串数组 的时候,就给他分配好内存了,要么你指定大小,要么根据初始化字符串常量自动分配大小。所以:使用strcat()函数时,要注意第一个字符串的空间是否足够再容纳第二个字符串,否则会溢出。也即,声明第一个字符串时只能用数组形式,且指定足够大的长度。(注意这个长度应该包含一个空字符’\0’) void strcat_test() { char s1[100] = "In this world, "; char s2[] = "the car is far away and the horse is slow."; strcat(s1,s2); puts(s1); puts(s2); }输出: In this world, the car is far away and the horse is slow. the car is far away and the horse is slow.如果写成char s1[] = "In this world, ";则会发生缓冲区溢出错误(或许某次运行时不会发生)。 比如:我这次运行把原来存储 s2处的数据破坏了(开头少了一个 t): In this world, the car is far away and the horse is slow. he car is far away and the horse is slow. 三、strncat()函数—strcat()的升级由于前面的strcat()函数可能会造成缓冲区溢出,所以我们可以使用strncat()函数来代替他,该函数新增第3个参数,用来指定最大添加字符数。(同样的,你不要忘记计算空字符了) 示例: void strncat_test() { char s1[20] = "Meet you, "; char s2[] = "love surge, see everything in the world, are romantic heart."; strncat(s1, s2, 20-strlen(s1)-1); puts(s1); puts(s2); }输出: Meet you, love surg love surge, see everything in the world, are romantic heart. 四、strcmp()和strncmp()—比较如何比较下列两个字符串是否相同? char s1[20] = "Hello, Tom."; char s2[15] = "Hello, Jay.";使用: if(s1 == s2)这肯定不对,s1、s2是地址,它们的值肯定不同。我们要比较的是字符串内容。 以使用C标准库中的strcmp()函数(用于字符串比较)。该函数通过比较运算符来比较字符串,就像比较数字一样。如果两个字符串参数相同,该函数就返回0,否则返回非零值(真或者说TRUE)。 示例: void strcmp_test() { char s1[20] = "Hello, Tom."; char s2[15] = "Hello, Jay."; printf("%d\n",strcmp(s1,s2)); printf("%d\n", strcmp("OK", "OK")); printf("%d\n",strcmp("A","B")); printf("%d\n", strcmp("A", "C")); printf("%d\n", strcmp("B", "A")); printf("%d\n", strcmp("d", "a")); }输出: 1 0 -1 -1 1 1说明: 函数比较的是字符串,不是整个数组,不用管两个数组大小是否相同;从左到右依次比较,直到出现一对不同的字符;输入参数是字符串(双引号),要比较单个字符(单引号)直接判断是否相等就行了;两个字符串相同,返回0;否则返回非0(前者比后者小返回-1,反之返回1,可能与编译器有关,有的返回这两个不同字符的ASCII码的差值)。strncmp()函数则通过低3个参数,指明只比较两个字符串的前 n 个字符是否相同。 printf("%d\n", strncmp("Fighting", "Fight",5));比较前5个字符,相同,返回0。 五、strcpy()和strncpy()—拷贝前面提到过,如果pts1和pts2都是指向字符串的指针,那么下面语句拷贝的是字符串的地址而不是字符串本身: pts2 = pts1;如果希望拷贝整个字符串,要使用strcpy()函数。 strcpy()将第2个参数指向的字符串被拷贝至第1个参数指向的数组中。拷贝出来的字符串被称为目标字符串,最初的字符串被称为源字符串。 strcpy()接受两个字符串指针作为参数,可以把指向源字符串的第2个指针声明为指针、数组名或字符串常量;而指向源字符串副本的第1个指针应指向一个数据对象(如,数组),且该对象有足够的空间储存源字符串的副本。记住,声明数组将分配储存数据的空间,而声明指针只分配储存一个地址的空间。 示例(接收一个用户输入,如果开头是I,则拷贝给s1): void strcpy_test() { char s1[20]; char s2[20]; fgets(s2,18,stdin); //gets_s(s2,18); if (!strncmp(s2, "I", 1)) strcpy(s1,s2); puts(s2); puts(s1); }输入输出: I love you more than i can say. I love you more t I love you more tstrcpy()函数还有两个有用的属性。第一,strcpy()的返回类型是char *,该函数返回的是第1个参数的地址。第二,第1个参数不必指向数组的开始。这个属性可用于拷贝数组的一部分。 例: char s3[20] = "I am your dad"; puts(s3); printf("%s\n",strcpy(s3+10,"son")); printf("%s\n", s3);输出: I am your dad son I am your sonstrcpy()和strcat()都有同样的问题,它们都不能检查目标空间是否能容纳源字符串的副本。拷贝字符串用strncpy()更安全,该函数的第3个参数指明可拷贝的最大字符数。 这里就不写例子了。 六、sprintf()函数—合并多个字符串sprintf()函数声明在stdio.h中,而不是在string.h中。该函数和printf()类似,但是它是把数据写入字符串,而不是打印在显示器上。因此,该函数可以把多个元素组合成一个字符串。sprintf()的第1个参数是目标字符串的地址。其余参数和printf()相同,即格式字符串和待写入项的列表。 示例: void sprintf_test() { char s1[50] = { "Hello, " }; sprintf(s1+strlen(s1),"%sI am %d yesrs old. ","i am Tom. ",18); puts(s1); }输出: Hello, i am Tom. I am 18 yesrs old. 七、其他可能用到的字符串函数(1)strstr()函数 原型: char *strstr(const char *s1,const char *s2);返回指向s1字符串中s2字符串首次出现的位置,没有则返回空指针。 例,用它来写一个函数,输出字符串中所有出现字母a的下标: void strstr_test() { char *s1 = " The Panda has a big head."; //printf("%zd\n",strlen(s1)-strlen(strstr(s1,"a"))); int i = 0; while (*(s1+i) != '\0') { if (strstr(s1 + i, "a") != NULL) { i = strlen(s1) - strlen(strstr(s1 + i, "a")); printf("%d\n",i); } i++; } }输出: 6 9 12 15 23(2)strchr()函数 char *strchr(const char * s, int c);如果s字符串中包含c字符,该函数返回指向s字符串首次出现的c字符的指针(末尾的空字符也是字符串的一部分,所以在查找范围内);如果在字符串s中未找到c字符,该函数则返回空指针。 (3)strrchr()函数 char *strrchr(const char * s, int c);该函数返回s字符串中c字符的最后一次出现的位置(末尾的空字符也是字符串的一部分,所以在查找范围内)。如果未找到c字符,则返回空指针。 八、ctype.h中的字符函数处理单个字符的函数。 有些函数涉及本地化,指的是为适应特定区域的使用习惯修改或扩展C基本用法的工具(例如,许多国家在书写小数点时,用逗号代替点号,于是特殊的本地化可以指定C编译器使用逗号以相同的方式输出浮点数,这样123.45可以显示为123,45)。注意,字符映射函数(如tolower)不会修改原始的参数,这些函数只会返回已修改的值。 单字节宽字节描述isalnumiswalnum是否为字母数字isalphaiswalpha是否为字母isloweriswlower是否为小写字母isupperiswupper是否为大写字母isdigitiswdigit是否为数字isxdigitiswxdigit是否为16进制数字iscntrliswcntrl是否为控制字符isgraphiswgraph是否为图形字符(例如,空格、控制字符都不是)isspaceiswspace是否为空格字符(包括制表符、回车符、换行符等)isblankiswblank是否为空白字符(C99/C++11新增)(包括水平制表符)isprintiswprint是否为可打印字符ispunctiswpunct是否为标点tolowertowlower转换为小写touppertowupper转换为大写不适用iswctype检查一个wchar_t是否是属于指定的分类不适用towctrans使用指定的变换映射来转换一个wchar_t(实际上是大小写的转换)不适用wctype返回一个宽字符的类别,用于iswctype函数不适用wctrans返回一个变换映射,用于towctrans几种常见的字符集: ASCII编码:单字节编码latin1编码:单字节编码gbk编码:使用一字节和双字节编码,0x00-0x7F范围内是一位,和 ASCII保持一致。双字节的第一字节范围是0x81-0xFEUTF-8编码:使用一至四字节编码,0x00–0x7F范围内是一位,和 ASCII 保持一致。其它字符用二至四个字节变长表示。 宽字节就是两个以上的字节。 九、把字符串转换为数字数字既能以字符串形式储存,也能以数值形式储存。把数字储存为字符串就是储存数字字符。例如,数字213以’2’、‘1’、‘3’、'\0’的形式被储存在字符串数组中。以数值形式储存213,储存的是int类型的值。 C要求用数值形式进行数值运算(如,加法和比较)。但是在屏幕上显示数字则要求字符串形式,因为屏幕显示的是字符。printf()和sprintf()函数,通过%d和其他转换说明,把数字从数值形式转换为字符串形式,scanf()可以把输入字符串转换为数值形式。C还有一些函数专门用于把字符串形式转换成数值形式。 假设你编写的程序需要使用数值命令形参,但是命令形参数被读取为字符串。因此,要使用数值必须先把字符串转换为数字。如果需要整数,可以使用atoi()函数(用于把字母数字转换成整数),该函数接受一个字符串作为参数,返回相应的整数值。 下面的函数都位于stdlib.h中。 (1)atoi() 将字符串形式的数字转为整数;字符串开头是数字,后面是字符,只转换开头的数字;字符串开头不是数字,返回0。例: printf("%d %d\n", atoi("123"),"123"); printf("%d\n", atoi("30 days")); printf("%d\n", atoi("Five 23 days"));输出: 123 -2111757740 30 0(2)atof 转成double (3)atol 转成long (4)strtol()、strtoul()、strtod() 转成long、unsigned long、double。 其中strtol()和strtoul()可以指定进制。 例: char number[] = "7f"; printf("%d\n", strtol(number,number+2,16)); printf("%d\n", strtol(number,number+2,10));输出: 127 7 十、命令行参数你可能见过两大形式的main()函数: int void main() { ... }或者: int void main(argc,**argv) { ... }一般我们用第一种形式的。 一般,我们在IDE中运行代码。 我们的程序写好之后,我们不可能总是打开IDE(如Visual Studio)来运行它,而是生成一个可执行程序,每次运行这个可执行程序即可。 在win或linux 的命令行输入可执行文件的名称即可运行程序(注意路径)。 比如: 在该路径下打开命令行,输入可执行程序名称,即可运行: 如果想要手动输入一下参数怎么办呢? 当然可以用scanf()、fgets()这些函数,上图中就是这么做的。 对应的代码可能是这样的: int main() { char str[20]; puts("Please input s string:"); fgets(str, 18, stdin); puts(str); return 0; }但使用命令行参数,则更加简单、灵活。 这时,代码可能是这样的: int main(int argc,char **argv) { puts("argv values are:"); for (int i = 0;i dist_test 666 "Hllo csdn." 你好 argv values are: dist_test 666 Hllo csdn. 你好如果你写了一个处理文件的程序,用这种方式指定输入输出文件是个不错的选择。 解读: C编译器允许main()函数没有或者有2个参数;有2个参数时,第一个为int型的值,称为参数计数,即argc(argument count);第二个为指针数组,用来保存你的输入字符串,即argv(argument value);argv的第一个字符串是你的程序的名字;后面则是你在命令行输入的字符串;第一个参数的值等于 1 + 你输入的字符串个数;在命令行输入字符串时,每个字符串的分隔符是空格,如果你输入的一个字符串包含多个单词,用双引号括起来就可以了。 十一、练习—字符串排序有如下指针数组: char *p[4] = { "Do your best this time.", "And i always believe in you.", "But you have not ", "What's the matter?" };排序函数: void str_sort(char *str[],int n) { char *temp; for (int i = 0;i if (strncmp(str[i], str[j],1) > 0) //前比后大为正 { temp = str[j]; str[j] = str[i]; str[i] = temp; } } } for (int k = 0;k |
今日新闻 |
推荐新闻 |
专题文章 |
CopyRight 2018-2019 实验室设备网 版权所有 |