字符串
2016-07-01 10:55
429 查看
字符串
一、字符串常量
大家一定要记得”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 12 int main() { char name ; 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 12 int main() { char name ; 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 12 int main() { char name ; 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 12 int main() { char name ; 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 12 int main() { char name ; 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 15 int main() { char a = "hello"; char b = "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 20 unsigned 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 20 unsigned int myStrlen(const char *str) { unsigned int len = 0; while(*str != '\0') { str++; len++; } return len; }
以上两个函数的主函数:
int main() { char str ; 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 20 char *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 = "hello"; char str2 = "feng xiao"; printf("%s", myStrcpy(str1, str2)); return 0; }
结果是:feng xiao
在使用返回指针值的函数的时候,必须在函数内对返回指针值的首地址进行赋值,否则,请看下面代码:
#include "stdio.h" #define N 20 char *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 = "hello"; char str2 = "feng xiao"; printf("%s", myStrcpy(str1, str2)); return 0; }
结果是:
结果就是没有结果!所以大家要谨记这一点。
相关文章推荐
- 如何组织构建多文件 C 语言程序(二)
- 数据库链接字符串查询网站
- 如何写好 C main 函数
- Flex字符串比较 还有Flex字符串操作
- Ruby中创建字符串的一些技巧小结
- ASP下经常用的字符串等函数参考资料
- 将字符串小写转大写并延时输出的批处理代码
- 将字符串转换成System.Drawing.Color类型的方法
- Lua和C语言的交互详解
- Lua源码中字符串类型的实现
- Lua性能优化技巧(四):关于字符串
- 字符串聚合函数(去除重复值)
- Ruby中的字符串编写示例
- 总结的5个C#字符串操作方法分享
- sqlserver中求字符串中汉字的个数的sql语句
- sql server字符串非空判断实现方法
- C#算法函数:获取一个字符串中的最大长度的数字
- VBS的字符串及日期操作相关函数
- C#实现将千分位字符串转换成数字的方法
- jquery 删除字符串最后一个字符的方法解析