三十、字符串
字符:人能看懂的图案
在计算机中字符都是以整数形式存储的,当需要显示成字符时,就会根据
ASCII码表中的对应关系显示出对应的符号或图案
'\0' 0 空字符
'0' 48
'A' 65
'a' 97
串:是一种数据结构,由一组连续的若干个类型相同的数据组成,末尾一定有一个结束标志
对于这种数据结构的处理都是批量性,从开始的地方一直处理到结束标志
字符串:
由字符组成的串形结构,结束标志是‘\0’
字符串的存在形式
字符数组:
char str[5] = {'1','3','4','2'};
由char组成的字符串要给'\0'留位置,使用的是栈内存,数据可以中途修改
字符串字面值:
"由双引号包含的若干个字符" 末尾自动补'\0'
字符串字面值以地址形式存在,字符数据存在在代码段,不可修改。修改一定段错误
注意:完全相同的字符串字面值,在代码段中只有一份
const char* p = "字符串字面值";
sizeof(p) 操作系统位数?4:8
sizeof("1234") 5 计算字符串字面值在代码段所占的内存字节数,包括'\0'
常用方式:
字符数组[] = "字符串字面值";
会自动给'\0'留位置,可以修改内容,初始化简单
赋值完成后字符串存在两份,一份在代码段,一份在栈内存(可修改)
字符串的输入输出:
输入:
char str[200]={};
scanf("%s",str);
不能输入带空格的字符串,
char *gets(char *s);
返回值:返回s,为了链式调用,一个函数的返回值直接作为另一个函数的参数。
能输入带空格的字符串,不限制输入的长度,有安全隐患,编译器会有警告。
char *fgets(char *s,int size,FILE *stream);
功能:从stream中最多输入size-1个字符到s中
s:字符数组
size:最多接收的字符个数+1
stream:stdin 相当于键盘文件 固定写
返回值:为了链式调用,一个函数的返回值直接作为另一个函数的参数。
如果输入超出size-1个字符,多出来的不接收
如果不足size-1,'\n'也会被接收
输出:
printf("%s",字符数组|字符串字面值);
int puts(const char *s);
功能:输出字符串
返回值:成功输出字符个数
注意:会自动打印换行
三十一、输出缓冲区
程序中要输出显示内容并不会立即显示到屏幕上,而是先存储在输出缓冲区,
当满足一定条件时才从缓冲区中显示到屏幕上。
1.遇到'\n'后,全部输出
2.遇到输入语句时,输出
3.当输出缓冲区(4K)满了
4.程序结束
5. Linux提供了 fflush(stdout); 手动刷新 仅Linux
三十二、输入缓冲区
程序并不是立即从键盘获取输入的内容,而是当按下回车后,终端输入的内容会
先存储到输入缓冲区中,然后执行输入函数再从输入缓冲区中读取数据到内容中。
1.当想要读取整型或浮点型数据,但是缓冲区中的数据是符号或字母的时候,读取失败;
数据会残留在缓冲区,影响接下来的数据的读取
解决:
先判断是否全部输入正确,如果不是,先清理缓存并重新输入,直到输入正确。
int a=-1,b=-1,c=-1;
while (3>scanf("%d%d%d",a,b,c))
{
printf("输入有问题,请重新输入");
stdin->_IO_read_ptr = stdin->_IO_read_end; //仅Linux
}
printf("%d %d %d",a,b,c);
2. fgets() 可以接收指定size-1个字符,如果有多余的字符,会残留在缓冲区,可能影响后面的数据
解决:
1.
fgets(str,size,stdin);
int len = 0;
while (str[len])
len++;
if('\n' != str[len-1])
{
scanf("%*[^\n]");(正则表达式)
从缓冲区中读任何数据,如果不是'\n',就继续读,直到遇到'\n',停止读取
scanf("%*c");
从缓冲区中读一个字符,并丢弃
}
2.
stdin->_IO_read_ptr = stdin->_IO_read_end;(只能在Linux/UNIX系统使用)
把输入缓冲区中的当前位置指针,移动到缓冲区末尾,相当于清理了输入缓冲区。
3.当先输入整型或浮点型,再输入字符。在输入字符、字符串时,前一次的输入会残留'\n'
影响后面的字符、字符串的输入
解决:
字符:
在后一次的输入前加空格
字符串:
scanf("%d",&num);
scanf("%*c");//这个是解决方法
gets(str);
三十三、字符串相关操作函数
(要能自己实现)
#include <string.h>
size_t strlen(const char *s);
功能:计算字符串长度(不包括 '\0')
strlen与sizeof区别
strlen是函数
sizeof是操作符
#include <string.h>
char *strcpy(char *dest, const char *src);
功能:把src拷贝给dest,相当于给dest赋值。
返回值:链式调用
#include <string.h>
char *strcat(char *dest, const char *src);
功能:把src追加到dest末尾,相当于合并两个字符串
返回值:链式调用
#include <string.h>
int strcmp(const char *s1, const char *s2);
功能:比较两个字符串大小。
从头开始,每一个字符一对一进行比较,按字典序,谁在前谁小。
一旦比较出结果,立即返回结果,后面不再比较。
返回值:
0 s1 == s2 (主要)
正数 s1 > s2
负数 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在haystrck中首次出现的位置,没有返回NULL
#include <stdio.h>
int printf(const char *format, ...);
int sprintf(char *str, const char *format, ...);
功能:把各种类型的数据输出给字符串str
int sscanf(const char *str, const char *format, ...);
功能:从str中解析读取数据到变量中。
返回值:成功解析出来的变量个数。
#include <string.h>
void *memcpy(void *dest, const void *src, size_t n);
功能:从src位置拷贝n个字节到dest的位置;
功能:链式调用
#include <string.h>
int memcmp(const void *s1, const void *s2, size_t n);
功能:比较两块内存的值,按字节比较,一旦出结果后面不再比较
返回值:
0 s1 == s2 (主要)
正数 s1 > s2
负数 s1 < s2