C语言学习笔记第十一天
字符:
在计算机中字符都是以整数形式存储的,当需要显示成字符时,就会根据ASCII码表中的对应关系显示出相应的符号或图案
字符(字面值) | ascall码值 | |
---|---|---|
‘\0’ | 0 | 空字符 |
‘0’ | 48 | |
‘A’ | 65 | |
‘a’ | 97 |
串:是一种数据结构,有一组连续的若干类型相同的数据组成,末尾一定有一个结束标志
对于这种数据结构的处理都是批量性的,从一开始的地方一直处理到结束标志停止
字符串:由字符组成的串行结构的结束标志是 ‘\0’
字符数组:
char str[5]={'a','b','c','d'};
由char类型组成的数组,需要为‘\0’预留位置,使用的是栈内存,数据可以中途修改的
字符串字面值:
“有双引号包含的若干个字符”
char str="abcd";
特点是末尾会自动补零,字符串字面值以地址形式存在,字符数据存在代码段,如果修改一定会产生段错误
常用方式:字符数组[]="字符串字面值"
,会自动给‘\0’预留位置,可以修改内容,初始化简单,赋值完成后字符串存在两份,一份在代码段,一份在栈内存
字符串本身是一个地址,但是sizeof算出来是字符串在代码段中占用空间(包括‘\0’),所以字符串跟数组的属性很像。
注意:完全相同的字符串字面值,在代码段中只存在一份
字符串输入:
char str[256]={};
scanf方法
scanf("%s",str);
注意scanf不能接收空格,遇到空格输入结束,scanf(“%s”,str);会在输入数据后默认加入‘\0’
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<len/2;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 <string.h>
原型:size_t strlen(const char *s);
作用:求s的字符长度,遇到‘\0’结束,但是‘\0’不计入长度
char *strcpy(char *dest, const char *src);
作用:src拷贝给dest,连同’\0’一起,但是后面字符不改变
char *strncpy(char *dest, const char *src, size_t n);
作用:src的n个字符拷贝给dest,连同’\0’一起,但是后面字符不改变
返回值用来链式调用
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<s2 |
>0 | s1>s2 |
作业1:自己实现strlen\strcpy\strcat\strcmp
其他小知识,包含头文件
<unistd.h>
后可以使用sleep和usleep(线程睡眠)
作业个人代码(老师还没讲):
/************************************
> 作者:杭电羊皮卷
> QQ:2997675141
> weixin:QQ2997675141
************************************/
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
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++)!='\0');
return start;
}
char* strcat_t(char* dest,const char* src)
{
char* p=dest;
while(*p){p++;};
while((*p++=*src++)!='\0');
return dest;
}
int strcmp_t(const char* s1,const char* s2)
{
while(*s1!='\0'&& *s2!='\0' && *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 = %d\n",strlen_t("abcdef"));
printf("strlen = %d\n",strlen("abcdef"));
printf("===========test2=================\n");
printf("strcat: %s\n",strcat_t(strdest,str));
printf("strcat: %s\n",strcat_t(strdest1,str));
printf("===========test3=================\n");
printf("strcmp: %d\n",strcmp_t("abcde","abcd"));
printf("strcmp: %d\n",strcmp("abcde","abcd"));
printf("===========test4=================\n");
printf("strcpy: %s\n",strcpy_t(str1,"abcd"));
printf("strcpy: %s\n",strcpy(str2,"abcd"));
return 0;
}