- C语言学习笔记第十一天
- 一、字符串
- 二、字符串的存在形式
- 三、字符串的输入输出
- 四、输入缓冲区(次重点)
- 五、输入缓存区(重点)
- 六、字符串相关操作函数
- 一、字符串
字符:
在计算机中字符都是以整数形式存储的,当需要显示成字符时,就会根据ASCII码表中的对应关系显示出相应的符号或图案
| 字符(字面值) | ascall码值 | |
|---|---|---|
| ‘ ’ | 0 | 空字符 |
| ‘0’ | 48 | |
| ‘A’ | 65 | |
| ‘a’ | 97 |
串:是一种数据结构,有一组连续的若干类型相同的数据组成,末尾一定有一个结束标志
对于这种数据结构的处理都是批量性的,从一开始的地方一直处理到结束标志停止
字符串:由字符组成的串行结构的结束标志是 ‘ ’
- 二、字符串的存在形式
字符数组:
char str[5]={'a','b','c','d'};
由char类型组成的数组,需要为‘ ’预留位置,使用的是栈内存,数据可以中途修改的
字符串字面值:
“有双引号包含的若干个字符”
char str="abcd";
特点是末尾会自动补零,字符串字面值以地址形式存在,字符数据存在代码段,如果修改一定会产生段错误
常用方式:字符数组[]="字符串字面值",会自动给‘ ’预留位置,可以修改内容,初始化简单,赋值完成后字符串存在两份,一份在代码段,一份在栈内存
字符串本身是一个地址,但是sizeof算出来是字符串在代码段中占用空间(包括‘ ’),所以字符串跟数组的属性很像。
注意:完全相同的字符串字面值,在代码段中只存在一份
- 三、字符串的输入输出
字符串输入:
char str[256]={};
scanf方法
scanf("%s",str);
注意scanf不能接收空格,遇到空格输入结束,scanf(“%s”,str);会在输入数据后默认加入‘ ’
gets方法
格式:char* gets(char* s);
可以输入带有空格的字符串,缺点是不限制输入长度,有安全隐患,编译器会有警告
返回值为s,为了链式调用,一个函数的返回值当作另一个函数的参数,
fgets方法
格式:char *fgets(char *s, int size, FILE *stream);
功能:从stream中最多输入size-1个字符到s中
s:最多接受的字符个数+1
size:最多接收的字符个数+1
stream:stdin相当于键盘文件,固定写
返回值:链式调用
如果输入超过size-1个字符,多出来不接受
如果输入不足size-1,‘n’也会接收
使用方法:fgets(str,10,stdin);
字符串输出
printf方法
printf("%s",str);
int puts(const char *s);
功能:输出字符串
返回值:成功打印的个数
注意:会自动打印换行符
练习1:实现一个判断字符串是否为回文串的函数
练习2:实现一个函数,把一个由数字字符组成的字符串转换成对应的整数
练习3:实现一个函数,把字符串逆序
个人答案如下:
//判断回文数
bool is_palindrome_str(const char* str,int len)
{
for(int i=0;i<=len/2;i++)
{
if(*(str+i)!=*(str+len-i-1))
{
return 0;
}
}
return 1;
}
//转换成对应的整数
int change(const char* str)
{
int num=0;
while(*str)
{
num=num*10+(*str++)-'0';
}
return num;
}
//字符串逆序
char* contrary_arr(char* str,int len)
{
char* str_start=str;
char t;
for(int i=0;i
t=*(str+i);
*(str+i)=*(str+len-i-1);
*(str+len-i-1)=t;
}
return str_start;
}
- 四、输入缓冲区(次重点)
程序中要输出显示的的内容并不会立即显示到屏幕上,而是先存到输出缓冲区中,当满足一定条件时才会从缓冲区中显示内容到屏幕上
条件:
- 遇到‘n’后
- 遇到输入语句后
- 当输入缓冲区满了会将所有的数据输出
- 程序结束时
- 手动刷新 fflash(stdout);
- 五、输入缓存区(重点)
程序并不是立即从键盘获取输入的内容,而是当按下回车后,终端输入的内容会先存储到缓冲区中,然后输入函数再从输入缓冲区中读取数据到内容中。
-
当想要读取整形或浮点型数据,但是缓存区中的数据是符号或字符时,读取会失败,数据会残留在缓存区中,影响接下来所有数据的读取
解决:在%c前面加上一个空格,将缓存区的n冲掉。判断scanf的返回值是否全部输入数据,如果不是,先清理输入缓冲区再重新输入,直到全部输入正确。
-
fgets可以接受指定size-1个字符,如果有多余的字符会残留到缓冲区中,可能会影响接下来的输入
-
当先输入整形浮点型数据,在输入字符或者字符串时,前一次输入中会残留n,影响了后面字符字符串的输入。
解决1:
- 先判断‘n’在不在字符串内,如果不在,则说明在缓冲区中,则执行2和3步骤,否则不执行。
- scanf("%*[^n]"),从缓存区中读任意字符并丢弃,直到遇到n,(n没有读取掉)
- scanf("%*c");从缓存区中读取一个字符,并且丢弃。
解决2:
把输入缓冲区中的当前位置指针,移动到缓冲区末尾,相当于清理了输入缓冲区(只能Linux/Unix下使用)
- stdin->_IO_read_ptr = stdin->_IO_read_end;
"%*[^n]"涉及到正则表达式,感兴趣上网搜,不必深究
- 六、字符串相关操作函数
头文件:inclulde
原型:size_t strlen(const char *s);
作用:求s的字符长度,遇到‘ ’结束,但是‘ ’不计入长度
char *strcpy(char *dest, const char *src);
作用:src拷贝给dest,连同’ ’一起,但是后面字符不改变
char *strncpy(char *dest, const char *src, size_t n);
作用:src的n个字符拷贝给dest,连同’ ’一起,但是后面字符不改变
返回值用来链式调用
char *strcat(char *dest, const char *src);
作用:将src追加到dest末尾,相当于合并两个字符串
返回值用来链式调用
int strcmp(const char *s1, const char *s2);
作用:比较两个字符串的大小
从头开始,每个字符一对一进行比较,按照字典序,谁出现在谁前面谁就小(谁ascall码大谁就大),一旦比较出结果,立即返回结果
以下s1和s2表示字符串(方便表示)
| 0 | s1=s2 |
|---|---|
| <0 | s2 |
| >0 | s1>s2 |
作业1:自己实现strlenstrcpystrcatstrcmp
其他小知识,包含头文件
后可以使用sleep和usleep(线程睡眠)
作业个人代码(老师还没讲):
#include#include #include int strlen_t(const char* s) { int i=0; while(s[i])i++; return i; } char* strcpy_t(char* dest,const char* src) { char* start=dest; while((*dest++=*src++)!=' '); return start; } char* strcat_t(char* dest,const char* src) { char* p=dest; while(*p){p++;}; while((*p++=*src++)!=' '); return dest; } int strcmp_t(const char* s1,const char* s2) { while(*s1!=' '&& *s2!=' ' && *s1++==*s2++); if(*s1-*s2<0) return -1; else if(*s1-*s2>0) return 1; else return 0; } int main(int argc,const char* argv[]) { char str[]="abcde"; char str1[]="1234"; char str2[]="1234"; char strdest[30]="123456"; char strdest1[30]="123456"; printf("===========test1=================n"); printf("strlen = %dn",strlen_t("abcdef")); printf("strlen = %dn",strlen("abcdef")); printf("===========test2=================n"); printf("strcat: %sn",strcat_t(strdest,str)); printf("strcat: %sn",strcat_t(strdest1,str)); printf("===========test3=================n"); printf("strcmp: %dn",strcmp_t("abcde","abcd")); printf("strcmp: %dn",strcmp("abcde","abcd")); printf("===========test4=================n"); printf("strcpy: %sn",strcpy_t(str1,"abcd")); printf("strcpy: %sn",strcpy(str2,"abcd")); return 0; }



