字符
在计算机中是以整型形式存储的,当需要显示时会根据ASCII表中的对应关系显示出相应的符号或图案
‘\0’ 0
‘0’ 48
‘A’ 65
‘a’ 97
%c %hhd
字符的输入
scanf("%c",&ch);
ch = getchar();
字符的输出
printf("%c",ch);
putchar(ch);
串
是一种数据结构,是由一组类型相同的若干个数据组成,末尾有结束标志
对于这种数据结构的处理都是批量性的 从开头位置一直处理到结束标志
字符串
由字符组成的串行结构,结束标志是 ‘\0’
字符串的输入
scanf("%s",地址); 缺点,不能输入空格
char gets(char *s);
//功能:输入字符串,并且可以接收空格
//返回值:链式调用(把一个函数的执行结果,通过返回值作为另一个函数的参数)
char *fgets(char *s, int size, FILE *stream);
/*
功能:可以设置输入的字符串的长度为size-1,超出部分不会接收,它会为'\0'预留位置
s:内存首地址
size:字节数
stream:stdin
注意:如果输入的字符不足size-1,最后的\n会被一起接收了
*/
字符串的输出:
printf("%s",地址);
int puts(const char *s);
/*
功能:输出一个字符串,会在末尾自动添加一个\n
返回值:成功输出的字符个数
*/
字符串的存在形式
字符数组
char str[10]={‘a’,‘b’,‘c’,…};
由char类型组成的数组,要为’\0’预留位置,初始化麻烦
使用的是栈内存,数据可以随意修改
字符串字面值
“由双引号包含的若干个字符”
在末尾隐藏一个’\0’
字符串字面值是以地址形式存在的,数据存储在代码段中,如果修改就会段错误
注意:它的结束标志是加在末尾的
printf("%d\n",sizeof(“123123”));
注意:字符个数+1
printf("%d\n",sizeof§);
注意:指针的字节数 4|8
多个一模一样的字符串字面值在代码段只有一份
常用方式:
字符数组[ ]=“字符串字面值”;
会自动给’\0’预留位置
赋值完成后字符串会存在两份,一份在代码段,另一份在栈内存(可以修改)
输出缓冲区
程序并不会立即把输出数据显示到屏幕上,而是先存储在输出缓冲区,当满足一定条件才显示
1、遇到 \n
2、程序结束
3、遇到输入语句
4、当缓冲区满4K时
5、fflush(stdout) 手动刷新
缓冲区机制可以提高数据的读写速度,并且可以让低速的输入输出设备与高速的CPU之间协调工作
输入缓冲区
程序并不会立即获取屏幕上输入的数据,而是按下回车键后程序才从输入缓冲区读取数据
解决1:
借助scanf返回值判断是否接收成功,如果接收过程有失败情况,可以先清理输入缓冲区,在重新循环接收数据,直到完全接收成功为止
1、当需要读取的是整型或浮点型时,而输入缓冲区中的数据是字符或符号时,此时读取会失败,数据会残留在输入缓冲区中,就会影响接下来的所有数据的读取
2、fgets可以指定读取size-1个字符,如果有多余的会残留在输入缓冲区中,影响下一次输入
解决2:
方法一:
必须确认输入缓冲区中有垃圾数据时,才能去读取丢弃输入缓冲区的垃圾数据,否则程序会停下来等待缓冲区中有一个\n
scanf("%*[^\n]");
表示从缓冲区中接收任意字符并丢弃,只要不是\n就一直进行,遇到\n才停下
scanf("%*c");
丢弃任意字符,把\n丢掉
方法二:
借助缓冲区的位置指针移动到缓冲区末尾,实现清理缓冲区的效果
只能在Linux系统下使用
stdin->_IO_read_ptr = stdin->_IO_read_end
3、当先输入整型、浮点型数据,再紧接着输入字符、字符串时前一次残留的’\n’或空格,会影响字符、字符串的输入
解决3:%c前面加空格
scanf(" %c",&ch);
字符串相关的常用操作
#include <string.h>
size_t strlen(const char *s);
//功能:计算字符串长度,不包括'\0'
//注意:sizeof 和 strlen 的区别
char *strcpy(char *dest, const char *src);
//功能:把src拷贝到dest,相当于给dest赋值 =
//返回值:链式调用
char *strcat(char *dest, const char *src);
//功能:把字符串src追加到dest的后面,相当于 +=
//返回值:返回dest,链式调用
int strcmp(const char *s1, const char *s2);
/*功能:比较两个字符串的大小,按照字典序比较,谁在前面谁小,只要比较出结果,立即返回,后面的不再比较
返回值:
s1 > s2 正数
s2 < s2 负数
s1 == S2 0
*/
char *strncpy(char *dest, const char *src, size_t n);
//功能:把src前n个字符拷贝给dest
char *strncat(char *dest, const char *src, size_t n);
//功能:把src前n个字符追加到dest后面
int strncmp(const char *s1, const char *s2, size_t n);
//功能:比较前n个字符的大小
自己实现的strlen\strcpy\strcat\strcmp
size_t strlen2(const char *s)
{
/*
int len=0;
while(s[len]!='\0')len++;
return len;
*/
const char* tmp = s;
while(*tmp)tmp++;
return tmp - s;
}
char *strcpy2(char *dest,const char *src)
{
/*
int i=0;
while(src[i]!='\0')dest[i]=src[i++];
dest[i]='\0';
return dest;
*/
char* tmp=dest;
while(*tmp++=*src++);
return dest;
}
char *strcat2(char *dest,const char *src)
{
/*
int i=0,j=0;
while(dest[i]!='\0')i++;
while(src[j]!='\0')dest[i++]=src[j++];
dest[i]='\0';
return dest;
*/
char* tmp=dest;
while(*tmp)tmp++;
while(*tmp++=*src++)
return dest;
}
int strcmp2(const char* s1,const char* s2)
{
/*
int i=0,j=0;
for(i=0,j=0;s1[i]==s2[j]&&s1[i]!='\0'&&s2[i]!='\0';i++,j++);
return s1[i]-s2[j];
*/
while(*s1&&*s1==*s2)s1++,s2++;
return *s1-*s2;
}
#include <stdlib.h>
int atoi(const char *nptr);
//功能:字符串转int类型
long atol(const char *nptr);
//功能:字符串转long类型
long long atoll(const char *nptr);
//功能:字符串转long long类型
double atof(const char *nptr);
//功能:字符串转double类型
#include <string.h>
char *strstr(const char *haystack, const char *needle);
//功能:查找haystack,是否存在needle
//返回值:needle首次在haystack中出现的位置,如果找不到返回NULL
char *strchr(const char *s, int c);
//功能:查找s中是否有字符c
//返回值:c在s中首次出现的位置,不存在返回值NULL
int sprintf(char *str, const char *format, ...);
/*
字符串拼接
功能:把各种类型数据输出到str中
返回值:拼接后str的长度
*/
int sscanf(const char *str, const char *format, ...);
/*
功能:从str中读取解析各种类型的数据
返回值:成功读取到的变量的个数
*/