/*
* 19_数组-字符数组与字符串.c
*
* Created on: 2015年7月7日
* Author: zhong
*/
#include
#include
#include
/**
*一:字符数组:就是存放字符的char[]数组
* 由于c语言中没有像java,C#中的String(字符串),只有存放字符 的字符型数组当字符串使用(java中的String类也是对字符数组进行封闭的)。
*
*二: 字符数组的定义:
* char c[5];
* c[0]='i'; c[2]='a'; //给数组元素赋值
* 由于字符型 数据是以整数形式存放(AscII代码),所以也可以定义int型的数组存放字符。 int c[10]; c[0]='i';
*三: 字符数组的初始化:
* char c[5]={'a','b','c','d','e'}; //和int数组一样初始化
* char c[5]={'a','b','c'}; //当初始化数组中的一部分元素时,剩下没有初始化的元素被系统初始化为'\0'
* char c[]={'a','b','c','d','e'}; //当被始全部时,前面[]中的长度可以不写
* char c[];//如果定义数组时不初始化,哪么各元素的值是不可预料的。
*
* char c[4][5]={{},{},{},{}}; //也可以定义一个二维字符数组并初始化值
*
*四:字符数组元素的引用:和其它数组一样,使用[下标]获得某个元素的值。
*五:字符串和字符串结束标志:
* 在c语言中,是将字符串作为字符数组来处理的。
* 字符串结束标志:以字符‘\0’作为结束标志。 如字符数组中存放n个字符,前面9个字符都不普通字符,第10个字符是'\0',
* 则认为数组中有一个字符串,其有效字符为9个。也就是说,在遇到字符'\0'时,表示字符串结束把厕所字符组成一个字符串。
* c语言用字符数组存储字符串常量时,会自动加一个'\0'作为结束符。
* 有了字符串结束标志,在程序中就可以检测'\0'的位置断定字符串是否结束。
*
* 六:用字符串形式给字符数组初始化:
* char c[]={"I am Student"};
* char c[]="I am Student";//可以省略{}
* 要注意的时,这时字符数组的长度不是可见的字符个数12(加空格),而是13,因为系统会自动在't'后面添加 '\0'表示字符串的结束。
* char c[10]="abcd"; //后面没在字符的六个下标元素全部被初始化为'\0';
*
* 注意:如果不是采用字符串形式给字符数组赋值,系统不会后面添加'\0';
* 如 char c[5]={'a','b','c','d','e'}; //它的长度只有5
* 可以手动为其加上'\0'字符串结束标志,以便使用 char c[]={'a','b','c','d','e','\0'};
*
* 由于'\0'作为字符串结束标志,当系统遇到'\0'时,停止了对字符串的输出
* 如char c[6]={'N','W','K','\0','a','b'}; //output: NWK '\0'后面的字符不会再输出 了
*
* 七:字符数组的输入与输出:
* 输入:只输出第一个'\0'之前的字符
* printf("%c", arr[i]); //每个字符每个字符输出,使用%c+数组下标
* printf("%s\n",arr); //整个字符串一次输出, 用%s+字符数组名称
* 输入:
* char c[6];
* scantf("%c",arr[i]);//一个个字符输入 %c+元素下标地址 要用&取得内存地址
* scanf("%s",c); //直接输入一个字符串给字符数组赋值 %s+数组名 :因为数组名代表数组的起始地址,所以不用加&
*
* 注意: 当输入带空格,只会将空格之前的字符传到数组中,数组后面的元素全部为'\0';
* 如 char c[5];
* scanf("%s",c);
* 当你输入:i am no 回车后
* c字符数组元素如下:{'i','\0','\0','\0','\0'} //只获取到一个字符
*
* 由于数组名称代表数组起始地址,所以可以直接输出数组名查看数组内存的起始地址
* char c[6];
printf("%x",c);//28ff30 以十六进制形式打印数组名
八:字符串处理函数
puts(字符数组名); 输出字符中的函数-将一个字符串(以'\0'结束的字符序列)输出一终端,可以包含转义字符
因为puts()函数是在头文件中声名的,所以要导入这个头文件
gets(字符数组)--输入字符串的函数:从终端输入一个字符串到字符数组中,并得返回一个函数值,这个函数值是字符数组的起始地址
因为gets()函数是在头文件中声名的,所以要导入这个头文件
strcat(数组1,数组2)-- 字符串连接函数,其作用是把两个字符数组中的字符串连接起,将数组2中字符接到数组1字串后面。 并返回数组1的内存地址
因为strcat(数组1,数组2)函数声名是在头文件 string.h里面的,所以要#include
strcpy(字符数组1,字符串2) 字符串复制函数:作用是将字符串2复制到字符数组1中去。
strcat(数组1,数组2)函数声名是在头文件 string.h里面的,所以要#include
strcmp(字符串1,字符串2); 字符串函数比较函数, 要#include
strlwr(字符串) 返回字符串的小写字母形式
strupr(字符串) 返回字符串的大写字母形式
* 函数声名都是在string.h里面
strlen(字符数组) 返回字符串的长度,是字符串实际的长度(不包含'\0'在内),不是数组的长度
*函数声名都是在string.h里面
使用方法都在下面clib_string_function_xxx()函数中。
更多的字符串处理方法,可以查看头文件 string.h里面对字符串处理函数进行了声名
*
*/
//封闭打印数组的函数
void printf_char_array(char arr[], int len) {
int i;
for (i = 0; i < len; i++) {
printf("%c", arr[i]); //每个字符每个字符输出,使用%c+数组下标
}
printf("\n");
}
void printf_char_array_2(char arr[]) {
printf("%s\n", arr); //整个字符串一次输出, 用%s+字符数组名称
}
void printf_string() {
char c[6] = { 'N', 'W', 'K', '\0', 'a', 'b' };
printf_char_array(c, 4);
}
void scantf_string() {
char c[6];
int i;
for (i = 0; i < 6; i++) {
scanf("%c", &c[i]); //一个个字符输入 %c+元素下标地址 要用&取得内存地址
}
scanf("%s", c); //直接输入一个字符串给字符数组赋值 %s+数组名 :因为数组名代表数组的起始地址,所以不用加&
printf("%s", c);
}
//-----------------c函数库中提供的字符串处理函数------------------------------
void clib_string_function_puts() {
//-------puts(字符数组名); 输出字符中的函数-将一个字符串(以'\0'结束的字符序列)输出一终端,可以包含转义字符
//因为puts()函数是在头文件中声名的,所以要导入这个头文件
// char str[]="nwk nwk nwk nwk"; //以字符串赋值的数组,系统自动添加'\0'结束,输出没问题 :nwk nwk nwk nwk
// char str[]={'a','b'}; //这个是普通的字符数组,并不以'\0'结尾 所以输出时会有问题:abH?(
char str[] = { 'a', 'b', '\0' }; //手动为字符数组添加'\0'结束标记,这样输出才不会有问题:ab
puts(str);
}
void clib_string_function_gets() {
//-----gets(字符数组)--输入字符串的函数:从终端输入一个字符串到字符数组中,并得返回一个函数值,这个函数值是字符数组的起始地址
//因为gets()函数是在头文件中声名的,所以要导入这个头文件
char string[20];
int p = gets(string); //从键盘输入:i am boy 系统会自动将字符赋值给string数组
//注意,由于系统会将字符赋值给数组,而数组又是固定长度的,所以输入字符不能超过数组长度-1;
//为什么只能输入数组长度-1个字符呢,因为系统默认会给数组加上'\0'结束标记,占用了一个元素
puts(string); //将刚刚输入的内容打印:i am boy
printf("\n这是数组的内存地址%d\n", p);
}
void clib_string_function_strcat() {
//---strcat(数组1,数组2)-- 字符串连接函数,其作用是把两个字符数组中的字符串连接起,将数组2中字符接到数组1字串后面。 并返回数组1的内存地址
//strcat(数组1,数组2)函数声名是在头文件 string.h里面的,所以要#include
char str1[] = "zhong ";
char str2[30] = "nwk";
//输出连接后的字符
strcat(str1, str2);
puts(str1); //因为将str2放到了str1后了,所以现在可以直接打印str1得到连接后的字符串:zhong nwk
/*注意:按理来说,因为将str2连接到str1中,所以str1的长度要足够大才行的,但是现在我的str1只能刚刚装下str1的字符
但是程序也没有报错,正常运行????????
*/
// puts(strcat(str1, str2)); //直接打印也行
// printf("%s\n", strcat(str1, str2)); //zhong nwk
}
void clib_string_function_strcpy_or_strncpy() {
/*strcpy(字符数组1,字符串2) 字符串复制函数:作用是将字符串2复制到字符数组1中去。
strcat(数组1,数组2)函数声名是在头文件 string.h里面的,所以要#include
*/
// char str[10]="nwk"; //如果str字符数组里面有内容,复制的时候会复盖掉
char str[10]; //数组长度必须足够大,以便装下str2里面的所有字符串,否则运行出错
char str2[]="NWKKKK";
strcpy(str,str2);
// strncpy(str,str2,3); 这个函数的作用和上面哪个差不多,只是可以指定将str2的前n个字符复制到str中。
// strcpy(str,"NWK"); 被复制的内容也可以直接是字符串
puts(str);
}
void clib_string_function_strcmp() {
/*
* strcmp(字符串1,字符串2); 字符串函数比较函数, 要#include
*
* 比较后返回的结果:
* 如果字符串1=字符串2,则函数值为0,
* 如果字符串1>字符串2,则函数值为一个正整个数
* 如果字符串1<字符串2,则函数值为一个负整数
*/
//int result=strcmp("123","134"); //返回-1
//如果全部字符相同,则认为两个字符串相等,返回0
//若出现不相同的字符,则以第1对不相同的字符的结果为准: 如123,134 第2个字符2和3不相等,因为2<3,所以返回一个负数
int result=strcmp("abc","acd"); //返回-1
//如果是字符,两个字符比较是按照字典的先后顺序,后面的为大, 比如上面: b