1:字符数组的定义
char 数组名[常量];
2:字符数组成员的引用
格式:数组名[下标](0开始n-1结束)
3:字符数组成员的存储
连续存储
4:字符数组的大小
字符数组的大小:系统需要为该字符数组在内存中开辟的存储空间的大小
5:字符数组的初始化
1:通过单个字符对字符数组进行初始化
1:完全初始化:(不是字符串,不是以'\0结尾)
例子:char buf[5]={'a','b','c','d','e'};
2:部分初始化:(是字符串)
例子:char buf[5]={'a','b'};
3:没有指定初始化值
例子:char buf[5]={};
4:没有指定成员个数(不是字符串)
例子:char buf[]={'a','b','c',''d,'e'};
2:通过字符串对字符数组进行初始化
1:完全初始化
例子:char buf[5]={"abcd"} | "abcd";
2:部分初始化
例子:char buf[5]="ab";
3:没有指定初始化值: 默认全为0(常用)
例子:char buf[5]="";
4:没有指定成员个数
例子:char buf[]=“abcd”;
#include <stdio.h>
int main(int argc, const char *argv[])
{
char buf1[] = {'a', 'b', 'c', 'd', 'd'};
char buf2[] = "abcd";
printf("sizeof(buf) = %lu\n", sizeof(buf1));
printf("sizeof(buf) = %lu\n", sizeof(buf2));
return 0;
}
6:字符串
在c语言中并没有提供一种单独的数据类型来保存字符串,所以通常把字符串保存在字符数组中,通过对字符数组的相关操作来操作字符串
字符串:用双引号“”括起来的若干个字符,并且以'\0结尾
字符串结束标识('\0'):系统自动添加在字符串的末位,无需程序员手动添加
'\0':ascii码值为0,一个不可显示的字符
c语言中的零:
1:数值0;
2:字符串结束标识'\0'
3:NULL
两个长度:
字符数组的长度:计算方法sizeof[数组名],系统需要为该字符 数组在内存中开辟的存储空间的大小
字符串的长度:计算方法strlen(数组名),字符串中首次出现\0以前的字符
数值型数组不是以'\0'结尾
#include <stdio.h>
#include <string.h>
#define SIZE 100
int main(int argc, const char *argv[])
{
char buf[SIZE] = "abcd\0abcedg\0djhkf";
printf("sizeof(buf) = %lu\n", sizeof(buf));
printf("strlen(buf+13) = %lu\n", strlen(buf+13));
printf("buf = %s\n", buf+13);
return 0;
}
7:字符串的输入和输出
字符串的输入:
1:scanf
例子:char buf[100]=“”;scanf("%s",buf);
缺点:scanf会把空格、回车和Tab键作为字符串的结束
2:gets:char buf[100]=“”;gets(buf);
缺点:gets函数不会对字符串越界进行检查
3:fgets:char buf[100]=“”;fgets(buf,sizeof(buf),stdin);
//stdin:标准输入
//stdout:标准输出
//stderr:标准错误输出
缺点:把'\n'保存在字符串中
字符串的输出:
1:printf:printf(“%s”,buf);
2:puts:puts(buf);
3:fputs:fputs(buf,stdout);
#include <stdio.h>
#include <string.h>
#define SIZE 100
int main(int argc, const char *argv[])
{
char buf[SIZE] = "";
//scanf("%s", buf);
gets(buf);
// fgets(buf, sizeof(buf), stdin);
// buf[strlen(buf)-1] = 0;
printf("buf = %s\n", buf);
puts(buf);
fputs(buf, stdout);
return 0;
}
8:与字符串相关的处理函数
1:strlen:计算字符串长度
函数名:strlen
原型:int strlen(char *s);
用法:#include <string.h>
功能:计算字符串s的长度
说明:返回s的长度,不包括结束符NULL。
#include <stdio.h>
#include <string.h>
#define SIZE 100
int main(int argc, const char *argv[])
{
char buf[SIZE] = "";
gets(buf);
printf("strlen(buf) = %lu\n", strlen(buf));
return 0;
}
2:bzero:清空字符串
函数名:bzero
原型:void bzero(void *s, int n);
参数说明:s 要置零的数据的起始地址; n 要置零的数据字节个数。
头文件:#include <string.h>
功能:置字节字符串s的前n个字节为零且包括‘\0’。
说明:bzero无返回值,并且使用string.h头文件,string.h曾经是posix标准的一部分,但是在POSIX.1-2001标准里面,这些函数被标记为了遗留函数而不推荐使用。在POSIX.1-2008标准里已经没有这些函数了。推荐使用memset替代bzero。
#include <stdio.h>
#include <string.h>
#define SIZE 100
int main(int argc, const char *argv[])
{
char buf[SIZE] = "";
gets(buf);
// bzero(buf, sizeof(buf));
bzero(buf, strlen(buf));
printf("buf = %s\n", buf);
return 0;
}
3:atoi:字符串转整型
函数名:atoi
原型:int atoi(const char *nptr);
参数说明:参数nptr字符串
头文件: #include <stdlib.h>
功能:把字符串转换成整型数。ASCII to integer 的缩写。
说明:如果第一个非空格字符存在,是数字或者正负号则开始做类型转换,之后检测到非数字(包括结束符 \0) 字符时停止转换,返回整型数。否则,返回零
#include <stdio.h>
#include <stdlib.h>
#define SIZE 100
int main(int argc, const char *argv[])
{
char buf1[SIZE] = "1234";
char buf2[SIZE] = "-1234";
printf("atoi(buf1)+ atoi(buf2) = %d\n", atoi(buf1)+atoi(buf2));
return 0;
}
4:strcpy:字符串的复制
原型声明:char *strcpy(char* dest, const char *src);
头文件:#include <string.h>
功能:把从src地址开始且含有NULL结束符的字符串复制到以dest开始的地址空间
说明:src和dest所指内存区域不可以重叠且dest必须有足够的空间来容纳src的字符串。
返回指向dest的指针。
#include <stdio.h>
#include <string.h>
#define SIZE 100
int main(int argc, const char *argv[])
{
char buf1[SIZE] = "";
char buf2[SIZE] = "";
gets(buf2);
strcpy(buf1, buf2);
printf("buf1 = %s\n", buf1);
printf("buf2 = %s\n", buf2);
return 0;
}
5:strcat:字符串的拼接
函数名:strcat
原型: char *strcat(char *dest, char *src);
参数说明:参数nptr字符串
头文件: #include <string.h>
功能:把src所指字符串添加到dest结尾处(覆盖dest结尾处的'\0')并添加'\0'
说明:src和dest所指内存区域不可以重叠且dest必须有足够的空间来容纳src的字符串。
返回指向dest的指针。
#include <stdio.h>
#include <string.h>
#define SIZE 100
int main(int argc, const char *argv[])
{
char buf1[SIZE] = "";
char buf2[SIZE] = "";
gets(buf1);
gets(buf2);
strcat(buf1, buf2);
printf("buf1 = %s\n", buf1);
printf("buf2 = %s\n", buf2);
return 0;
}
6:strcmp:字符串的比较
函数名:strcmp
原型:int strcmp(const char *s1, const char * s2);
所在头文件:#include <string.h>
功能:比较字符串s1和s2。
一般形式:strcmp(字符串1,字符串2)
说明:
当s1<s2时,返回为负数 注意不是-1
当s1==s2时,返回值= 0
当s1>s2时,返回正数 注意不是1
即:两个字符串自左向右逐个字符相比(按ASCII值大小相比较),直到出现不同的字符或遇'\0'为止。
#include <stdio.h>
#include <string.h>
#define SIZE 100
int main(int argc, const char *argv[])
{
char buf1[SIZE] = "";
char buf2[SIZE] = "";
int re = 0;
gets(buf1);
gets(buf2);
re = strcmp(buf1, buf2);
if (re > 0){
printf("buf1 > buf2\n");
} else if (re == 0){
printf("buf1 = buf2\n");
} else {
printf("buf1 < buf2\n");
}
return 0;
}
7:strchr:字符串中查找某个字符
函数名:strchr
char *strchr(const char* _Str,int _Val)
char *strchr(char* _Str,int _Ch)
头文件:#include <string.h>
功能:查找字符串s中首次出现字符c的位置
说明:返回首次出现c的位置的指针,返回的地址是字符串在内存中随机分配的地址再加上你所搜索的字符在字符串位置,如果s中不存在c则返回NULL。
#include <stdio.h>
#include <string.h>
#define SIZE 100
int main(int argc, const char *argv[])
{
char buf[SIZE] = "";
char ch = 0;
gets(buf);
ch = getchar();
printf("%s\n", strchr(buf, ch));
return 0;
}
8:strstr:字符串中查找某个子串
函数名: strstr
头文件:#include <string.h>
函数原型:char *strstr(const char *str1, const char *str2);
语法:* strstr(str1,str2)
str1: 被查找目标 string expression to search.
str2: 要查找对象 The string expression to find.
返回值:该函数返回str2第一次在str1中的位置,如果没有找到,返回NULL
#include <stdio.h>
#include <string.h>
#define SIZE 100
int main(int argc, const char *argv[])
{
char buf1[SIZE] = "";
char buf2[SIZE] = "";
gets(buf1);
gets(buf2);
printf("%s\n", strstr(buf1, buf2));
return 0;
}
9:实现字符串处理函数的基本功能
1:my_strlen
#include <stdio.h>
#define SIZE 100
int main(int argc, const char *argv[])
{
char buf[SIZE] = "";
int i = 0;
gets(buf);
for (i=0; buf[i]!=0;i++);
printf("i = %d\n", i);
return 0;
}
2:my_bzero
#include <stdio.h>
#define SIZE 100
int main(int argc, const char *argv[])
{
char buf[SIZE] = "";
int i = 0;
gets(buf);
for (i=0; buf[i]!=0; i++){
buf[i] = 0;
}
printf("buf = %s\n", buf);
return 0;
}
3:my_atoi
“1237”
1237
#include <stdio.h>
#define SIZE 100
int main(int argc, const char *argv[])
{
char buf[SIZE] = "";
int i = 0;
int num = 0;
gets(buf);
for (i=0; buf[i]!=0; i++){//"37968"
//num=3//num=37//num=379//num=3796//num=37968
num = num*10 + buf[i]-'0';
}
printf("num = %d\n", num);
return 0;
}
1:取出这个字符‘1’——>1
2:1——>1000
4:my_strcpy
buf1 = “”
buf2 = “sdfkjhsdf”;
#include <stdio.h>
#define SIZE 100
int main(int argc, const char *argv[])
{
char buf1[SIZE] = "";
char buf2[SIZE] = "";
int i = 0;
gets(buf2);
for (i=0; buf2[i]!=0; i++){
buf1[i] = buf2[i];//复制字符
}
buf1[i] = buf2[i];//复制\0
printf("buf1 = %s\n", buf1);
printf("buf2 = %s\n", buf2);
return 0;
}
5:my_strcat
buf1 = “bei jing ”;
buf2 = “huan ying nin”;
1:buf1的末尾
2:buf2复制到buf1中
#include <stdio.h>
#define SIZE 100
int main(int argc, const char *argv[])
{
char buf1[SIZE] = "";
char buf2[SIZE] = "";
int i = 0;
int j = 0;
gets(buf1);
gets(buf2);
//1:找buf1的末尾(i记录了buf1的末尾)
for (i=0; buf1[i]!=0; i++);
//2:把buf2中的内容复制到buf1中
for (j=0; buf2[j]!=0; j++){
buf1[i+j] = buf2[j];
}
buf1[i+j] = buf2[j];//复制\0
printf("buf1 = %s\n", buf1);
printf("buf2 = %s\n", buf2);
return 0;
}
6:my_strcmp
#include <stdio.h>
#define SIZE 100
int main(int argc, const char *argv[])
{
char buf1[SIZE] = "";
char buf2[SIZE] = "";
int i = 0;
gets(buf1);
gets(buf2);
for (i=0; (buf1[i]!=0)&&(buf2[i]!=0); i++){//同时便利buf1和buf2
if (buf1[i] != buf2[i]){//找到第一个不相同的字符
break;
}
}
printf("buf[%d]-buf2[%d] = %d\n", i, i, buf1[i]-buf2[i]);
return 0;
}
7:my_strchr
buf = “abcdefg”
ch = ‘c’
1:遍历buf
2:buf[i] == ch
#include <stdio.h>
#define SIZE 100
int main(int argc, const char *argv[])
{
char buf[SIZE] = "";
char ch = 0;
int i = 0;
gets(buf);
ch = getchar();
for (i=0; buf[i]!=0; i++){//遍历buf
if (buf [i] == ch){//找到该字符
break;
}
}
if (buf[i] == 0){
printf("null\n");
} else {
printf("%s\n", buf+i);
}
return 0;
}
8:my_strstr
buf1 = “bei jing you ge mao zhu xi”
buf2 = “you”
1:遍历buf1
2:遍历buf2
#include <stdio.h>
#define SIZE 100
int main(int argc, const char *argv[])
{
char buf1[SIZE] = "";
char buf2[SIZE] = "";
int i = 0;
int j = 0;
gets(buf1);
gets(buf2);
for (i=0; buf1[i]; i++){//遍历buf1
for (j=0; buf2[j]; j++){//遍历buf2
if (buf1[i+j] != buf2[j]){//有一个字符不匹配
break;//没找到
}
}
if (buf2[j]==0){//找到了
break;
}
}
if (buf2[j]==0){
printf("%s\n", buf1+i);
} else {
printf("null\n");
}
return 0;
}
课后练习:
1. 给定某个字符数组,统计数组中所有英文字符的个数,比如“123fdd”中有3个。
2. 给定某个字符数组,统计数组中所有英文字符和阿拉伯数字的个数,比如“123fdd”中有英文字符有3个,数字3个。
3. 给定某个拥有5个元素的字符数组,数组的成员都有阿拉伯字符构成,试着将该数组转换成一个整数,比如字符数组的内容是:{‘1’,’2’,’3’,’3’,’2’} 则将被转换成12332。
4. 给定一个完全由英文字符构成的数组,将数组中的小写字母转换成大写字母,大写字母转换成小写字母并输出。例如“abcGGG”转化为“ABCggg”。
5. 给定一个完全由英文字符构成的数组,将数组中下标为偶数的字符都转换为大写(如果原来是大写则不变)。
6. 给一个完全由英文字符构成的字符数组加密,加密原则如下,除了字符‘Z’和‘z’之外,每个字符变成ASCII码值比它大1的字符,也就是‘A’变成‘B’。‘Z’者‘z’转化为‘A’或者‘a’。
7. 计算某个由英文、数字以及标点符号构成的数组的总宽度,其中英文字符的宽度为1cm,数字宽度为0.5cm、标点符号宽度为0.8cm。
8. 接上题,如果规定行的宽度为10cm,将某个字符长度超过50的字符串截断,恰好使10cm宽的行能容纳。输出这个被截断的子数组。
9. 30. 给定一个英文句子,单词之间用1个空格分开,求出第2个单词的偏移位置。例如“Professor du comes from Korea”的偏移位置是10。
10. 给定一个英文句子,单词之间用1个空格分开,求其中所有单词的数量。
11. 给定两个字符数组,将这两个拼接起来放在第一个数组中(假定第一个数组足够长),比如“abc”和“123”构成“abc123”。
12.独立实现8个字符串处理函数的基本功能