【C 字符串】02 常用字符串函数(命令行参数) 您所在的位置:网站首页 strcmp函数在哪个数据库 【C 字符串】02 常用字符串函数(命令行参数)

【C 字符串】02 常用字符串函数(命令行参数)

2024-01-24 19:45| 来源: 网络整理| 查看: 265

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 t

strcpy()函数还有两个有用的属性。第一,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 son

strcpy()和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 实验室设备网 版权所有