C语言学习
字符串
字符串以字符数组形式存在
不能用运算符对字符串进行运算
可以通过数组的方式进行遍历字符串
字符串与字符数组区别
字符数组char word[] = {'H','e','l','l','o','!'};
字符串 char word[] = {'H','e','l','l','o','!','/0'};
0与’/0’是一样的,但与’0’不同
0与’/0’是标志字符串的结束,但不是字符串的一部分,计算长度时不包含这个0
字符串以数组形式存在,以数组或指针形式访问
字符串变量
char *str = "Hello";
char word[] = "Hello";
char line[10] = "Hello"; //占6个位置,因为有个'/0'
字符串常量
"Hello"
连续的字符串常量,会被自动连接到一起
char *s = "Hello,world";
"Hello,world"在代码段,只读类型
s是一个指针,初始化为指向一个字符串常量
由于该常量在代码段,所以s其实是const char *s
如果想要进行修改字符串,应定义为:
char s[]="Hello,world";
该"Hello,world"可进行写操作
总结上述:
char *s = "Hello,world";
- 指针:不知道这个字符串在哪
- 处理参数,动态分配空间
char s[]="Hello,world";
- 数组:这个字符串就在这
- 作为本地变量空间自动被回收
构造字符串 -> 数组
处理字符串 -> 指针
字符串赋值
char *t = "title";
char *s;
s = t;
并没产生新的字符串,只是指针 s 指向了指针 t 所指的字符串,对 s 操作其实就是对 t 做操作
字符串输入输出
char string[8]; //最多接收7个字符
scanf("%s",string); //输入,不需要&取地址符
printf("%s",string); //输出
scanf读入的是一个单词(空格、tab、回车为止)
scanf是不安全的,因为不知道要输入的内容长度
scanf("%7s",string);//输入7个字符,多余删掉
字符串数组
char **a
a是一个指针,指向另一个指针,那个指针指向一个字符串
char a[][10] != char *a[]
字符串函数
单字符输入输出
putcher
向标准输出写一个字符
int putcher(int c);
返回写了几个字符,EOF(-1)表示写失败
getchar
从标准输入读入一个字符
int getchar(void);
示例:
//单字节输入输出
int main(void)
{
int ch;
while ((ch = getchar())!=EOF)
{
putchar(ch);
}
printf("EOF\n");//只有CTRL+C才结束
system("pause");
}
string.h
strlen
szie_t strlen(const char *s);
返回s的字符串长度(不包括结尾的\0)
sizeof会包括结尾的\0
int mylen(const char *s) //strlen的功能实现
{
int cnt = 0;
while(s[cnt]!='\0')
{
cnt ++;
}
return cnt;
}
strcmp
int strcmp(const char *s1,const char *s2);
比较两个字符串
返回:0: s1 = s2 1(大于0的值,差值): s1 > s2 -1(小于0的值,差值): s1 < s2
示例:
int main(void)
{
char a[] = "abc";
char b[] = "Abc";
printf("%d\n",strcmp(a,b));
system("pause");
}
//输出为1,比较的是ASII的大小,第一个大则大,从第一个开始往下判断
//自己编写strcmp
int mycmp(const char *s1,const char *s2)
{
int cnt = 0;
while ((s1[cnt] == s2[cnt]) && (s1[cnt] != '\0'))
{
cnt++;
}
return s1[cnt] - s2[cnt];
}
strcpy****危险函数,存在安全问题,空间不够怎么办
char *strcpy(char *restrict dst,const char *restrict src);
把src(源)的字符串拷贝到dst(目的)中,返回dst,restrict表明src与dst不重叠
restrict表示这一块内存的访问方式只能是这个指针,其他指针或者方式都不行
安全版本:
char *strncpy(char *restrict dst,const char *restrict src,size_t n);
//复制字符串
char *dst = (char*)malloc(strlen(src)+1);
strcpy(dst,src);
//示例
int main(void)
{
char src[] = "hallo";
char *dst = (char*)malloc(strlen(src)+1);
strcpy(dst,src);
printf("src:%s,dst:%s",src,dst);
system("pause");
}
//自己编写strlen
char *mycpy(char *dst,const char *src)
{
char *ret = dst;
while (*src != '\0')
{
*dst++ = *src++;
}
*dst = '\0';
return ret;
}
strcat****危险函数,存在安全问题,空间不够怎么办
char *strcat(char *restrict s1,const char *restrict s2);
把s2拷贝到s1的后面,接成一个长字符串,返回s1,s1必须有足够的空间
安全版本:
char *strcat(char *restrict s1,const char *restrict s2,size_t n);
字符串中找字符:strchr
char *strchr(const char *s,int c);//从左
char *strrchr(const char *s,int c);//从右
返回第一次找到的位置(指针),没找到返回NULL
//示例
int main(void)
{
char a[] = "hello";
char *p = strchr(a,'l');
printf("%s",p);
system("pause");
}//输出为 llo
//找到第二个
int main(void)
{
char a[] = "hello";
char *p = strchr(a,'l');
char *t = strchr(p+1,'l');
printf("%s",t);
system("pause");
}//输出为 lo
//找到字符并把后面东西赋给另一个字符串
int main(void)
{
char a[] = "hello";
char *p = strchr(a,'l');
char *t = (char*)malloc(sizeof(p));//strlen需要+1(后面的\0)
strcpy(t,p);
printf("%s",t);
free(t);
system("pause");
}
//找到字符前面的一段
int main(void)
{
char a[] = "hello";
char *p = strchr(a,'l');
char c = *p;
*p = '\0';
printf("%s\n",a);
char *t = (char*)malloc((strlen(a)-strlen(p))+1);
strcpy(t,a);
printf("%s",t);
*p = c;
printf("%s",a);
free(t);
system("pause");
}
字符串中找字符串:strstr
char *strstr(const char *s1,const char *s2);`
char *strcasestr(const char *s1,const char *s2);//忽略大小写`