字符串
来源:互联网 发布:苹果c语言编程软件 编辑:程序博客网 时间:2024/06/02 19:07
字符串
一、字符串常量
大家一定要记得”a”是字符串常量,而’a’是字符常量。
所谓字符串就是有若干个字符常量组成以’\0’结尾的字符序列;
二、字符串的初始化
一般式:
char str[6] = {'h', 'e', 'l', 'l', 'o', '\0'}
这是一个长度为6的字符数组,是一个长度为5的字符串。
注意:如果没有’\0’结尾,那么这个字符数组就不是一个字符串。
请看下面的这几个定义:
char str[] = {'h', 'e', 'l', 'l', 'o', '\0'}; //这是对的;char str[] = {'h', 'e', 'l', 'l', 'o'}; //这是错的;
在不给字符数组给定长度的情况下,必须在其末尾添加’\0’,才能作为字符串来使用。
精简式
char str[] = {"hello"}; //这两个是对的;char str[] = "hello";
·多个字符串存储的方法
此时,我们需要借助二维字符数组来存储;数组的第一维定义了字符串的个数可省略,第二维定义了字符串的长度,而且第二维长度定义时是不能省略的。二维定义的长度如果大于实际提供的字符长度的话,剩余会以’\0’填充。
char weekday[][10] = {"sunday", "monday", "tueaday", "wednesday", "thursday", "friday", "saturday"};
三、字符指针
字符指针其实还是数组指针,也是一毛一样,因为字符指针说白了其实他就是字符数组指针,下面来看几个例子:
char *pa;pa = "hello";
等价于
char *pa = "hello";
对于字符指针来说:因为字符串保存在只读的常量存储区中,所以可以修改指针pa的指向:
pa = "shuaige";
但是不能修改他所指向的存储单元的值(也就是进行写操作)
*pa = 'w';
对于字符数组来说:还有就是看下面这段代码:
char str[] = "hello";char *pa = str; //他其实指向的是str[0];
由于数组名是地址常量,所以他的值是不可修改的,而pa的指向依然是可以修改的,但是在这里指向的是字符串不是存储单元,所以pa指向的字符串也是可以更改的:
*pa = 'w' //等价于pa[0] = 'w'或者是str[0] = 'w';
四、字符串的访问和输入输出
1、访问
和其他类型数组一样,我们可以通过下标来访问数组中的元素,str[0]访问的就是’h’;
还可以通过字符指针来访问,字符串指针pa指向了字符数组str的首地址,既可以通过*(pa+i)来索引第i+1个元素,也可以通过pa++的形式来移动指针,使pa指向字符串中的某个字符。
注意不能用str++来指向字符,因为数组名是一个地址常量,其值是不能被改变的。
2、输入输出
#include "stdio.h"#define N 12int main(){ char name[N]; printf("Please input your name:\n"); scanf("%s", name);; printf("hello %s!\n", name); return 0;}
结果是:
Please input your name:
xiao
hello xiao!
Please input your name:
feng xiao
hello feng!
对比两次的结果,我们得出:用scanf()按S格式符不能输入带空格的字符串。
所以我们引入了gets()字符串处理函数
gets()可以输入带空格的字符串,以回车符作为字符串的终止符,同时将回车符从缓冲区中读走,但并不会将回车符作为字符串的一部分,而scanf()不会读走回车符,回车符还在缓冲区中。
#include "stdio.h"#define N 12int main(){ char name[N]; printf("Please input your name:\n"); gets(name); printf("Hello %s", name); return 0;}
结果是:
Please input your name:
feng xiao(输入)
Hello feng xiao(输出)
这次他就能处理带空格的字符串了;
接下来我来说下一个字符串处理函数puts():
函数puts()相对于gets()他就没什么特色了,他其实就是和printf()一样,puts()依次输出储存单元中的字符,直到遇见’\0’输出结束,而且会自动添加一个换行;
#include "stdio.h"#define N 12int main(){ char name[N]; printf("Please input your name:\n"); gets(name); puts(name); return 0;}
结果是:
Please input your name:
feng xiao(输入)
feng xiao(输出)
还有一点就是gets()和puts()都是c语言的库函数,所以使用时要声明#include “stdio.h”;
除此之外还可以用字符指针实现编程:
#include "stdio.h"#define N 12int main(){ char name[N]; char *pa; pa = name; printf("Please input your name:\n"); gets(pa); puts(pa); return 0;}
结果与上面的一致;但是不知道你看出来没有,这里无论输入输出都用的是指针,而且是没有取值操作符的指针,看来这就是字符指针的魅力所在吧;还有注意的一点是在使用字符串指针的时候,要确保字符指针一定要指向一个数组的首地址。
其实gets()函数他还是有缺陷的,他不能限制输入字符串的长度,进而引起缓冲区溢出;
所以呢,fgets()就此诞生,他可以限制字符串的输入长度,下面来了看一下他的语法:
fgets(name, sizeof(name), stdin;
#include "stdio.h"#define N 12int main(){ char name[N]; printf("Please input your name:\n"); fgets(name,sizeof(name), stdin); printf("hello %s!\n", name); return 0;}
结果是:
Please input your name:
feng xiao hao shuai(我们输入了12+9=21)个字符;
hello feng xiao !(输出)
五、字符串处理函数
函数strlen直接就返回串str的长度!#include"string.h"main(){ int k; static char st[]="C language"; k=strlen(st); printf("The lenth of the string is %d\n",k);}
结果是:The lenth of the string is 10
函数名: stpcpy功 能: 拷贝一个字符串到另一个用 法: char *stpcpy(char *destin, char *source);程序例:#include <stdio.h>#include <string.h>int main(void){ char string[10]; char *str1 = "abcdefghi"; strcpy(string, str1); printf("%s\n", string); return 0;}
结果是:abcdefghi
#include "stdio.h"#include "string.h"#define N 15int main(){ char a[N] = "hello"; char b[N] = "fengxiao"; strcpy(a, b); printf("%s", a); return 0;}
结果是:fengxiao
值得注意的是复制之后,destin中的内容会被覆盖; 要确保destin的大小能够存放的下source;
函数名: strcat功 能: 字符串拼接函数用 法: char *strcat(char *destin, char *source);程序例:#include <string.h>#include <stdio.h>int main(void){char destination[25];char *blank = " ", *c = "C++", *Borland = "Borland";strcpy(destination, Borland);strcat(destination, blank);strcat(destination, c);printf("%s\n", destination);return 0;}
结果是:Borland C++
函数名: strcmp功 能: 串比较用 法: int strcmp(char *str1, char *str2);看Asic码,str1>str2,返回值 > 0;两串相等,返回0程序例:#include <string.h>#include <stdio.h>int main(void){char *buf1 = "aaa", *buf2 = "bbb", *buf3 = "ccc";int ptr;ptr = strcmp(buf2, buf1);if (ptr > 0) printf("buffer 2 is greater than buffer 1\n");else printf("buffer 2 is less than buffer 1\n");ptr = strcmp(buf2, buf3);if (ptr > 0) printf("buffer 2 is greater than buffer 3\n");else printf("buffer 2 is less than buffer 3\n");return 0;}
结果是:
buffer 2 is greater than buffer 1
buffer 2 is less than buffer 3
比如说现在有两个字符串 char str1[] = “hello China”/char str2[] = “hello”,现在用strcmp来比较的话:strcmp(str1, str2),结果必然是大于0的。因为str2的结尾是以’\0’结束的,’\0’的ASCII值是0,是ASCCII最小的了,而空格的ASCII值为32;所以当字符串前面的部分相同的情况下,字符串长的一定大于字符串短的。
六、向函数传递字符串
1、字符串数组作为参数传递给函数
#include "stdio.h"#define N 20unsigned int myStrlen(const char str[]){ int i; unsigned int len = 0; for(i=0;str[i]!='\0';i++) { len++; } return len;}
2、字符串指针作为参数传递给函数
#include "stdio.h"#define N 20unsigned int myStrlen(const char *str){ unsigned int len = 0; while(*str != '\0') { str++; len++; } return len;}
以上两个函数的主函数:
int main(){ char str[N]; printf("Please input your string:"); gets(str); printf("The string lenght is:%u\n", myStrlen(str)); return 0;}
结果是:
Please input your string:feng xiao hao shuai (输入)
The string lenght is:19 (输出)
大家一定会问为啥在定义形参的时候要在前面添加一个const,这是为了防止实参在函数中被意外的修改,所以在形参前面添加了类型限制符const;
七、从函数返回字符串指针
在第五个模块字符串处理函数中,我们就见到了,函数返回字符串指针的原型:
char *strcpy(char *str1, char *str2);char #strcat(char *str1, char *str2);
函数之间的握手(沟通)就是通过函数参数和返回值来进行的,在这我们讨论的是让返回指针值的函数返回一个地址,我们通过地址进而获得数据值;
值得注意的大家一定要将返回指针值的函数
char *f()
和函数指针区分开来
char (*f)()
为了让大家跟好的理解,看一段代码:
#include "stdio.h"#define N 20char *myStrcpy(char *str1, char *str2){ char *pstr = str1; //要输出的字符串首地址必须预先赋给一个字符指针; while(*str2 != '\0') { *str1 = *str2; //这里赋值操作的时候必须是值对值的,不能str1++ == str2++,这是错误的; str1++; str2++; } *str1 = '\0'; // 在字符串末尾添加字符串结束标志; return pstr; //输出操作后,字符串的首地址; }int main(){ char str1[N] = "hello"; char str2[N] = "feng xiao"; printf("%s", myStrcpy(str1, str2)); return 0;}
结果是:feng xiao
在使用返回指针值的函数的时候,必须在函数内对返回指针值的首地址进行赋值,否则,请看下面代码:
#include "stdio.h"#define N 20char *myStrcpy(char *str1, char *str2){// char *pstr = str1; //要输出的字符串首地址必须预先赋给一个字符指针; while(*str2 != '\0') { *str1 = *str2; //这里赋值操作的时候必须是值对值的,不能str1++ == str2++,这是错误的; str1++; str2++; } *str1 = '\0'; // 在字符串末尾添加字符串结束标志; return str1; //输出操作后,字符串的首地址; }int main(){ char str1[N] = "hello"; char str2[N] = "feng xiao"; printf("%s", myStrcpy(str1, str2)); return 0;}
结果是:
结果就是没有结果!所以大家要谨记这一点。
- 字符串
- 字符串
- 字符串
- 字符串
- 字符串
- 字符串
- 字符串
- 字符串
- 字符串
- 字符串
- 字符串
- 字符串
- 字符串
- 字符串
- 字符串
- 字符串
- 字符串
- 字符串
- 让你流泪的不是毕业,而是无法再重走一次的青春
- Eclipse配置相关
- Android PieChart 饼图控件
- [思考汇聚]杨小凯:后发劣势
- java笔记之使用Mybatis-Generator自动生成Dao、Model、Mapping相关文件2种方法
- 字符串
- android:configChanges属性
- Android clipChildren用法
- 呵呵!回首已枉然
- laravel框架初次使用
- php 获取今日、昨日、上周、本月的起始时间戳和结束时间戳的方法
- Objective-C中的各种遍历(迭代)方式
- mybatis 中的<![CDATA[ ]]>
- 【android基础开发】省钱达人UI—初级开发练手的好代码