字符串的常用函数:
功能:计算字符串长度,但是结果不包括’\0’
返回值:返回字符串中字符的个数
#include <string.h>
(size_t strlen(const char *s);
功能:把src拷贝到dest中,相当于给dest赋值
返回值:dest(链式调用)
char *strcpy(char *dest,const char *src);
功能:从src位置中拷贝n个字节到dest中
void *memcpy(void *dest, const void *src, size_t n)
int arr[5] = {1,2,3,4,5};
int *p = malloc(sizeof(int)*5);
memcpy(p,arr,sizeof(arr));
for(int i = 0; i<5; i++)
{
printf("%d ",p[i]);
}
功能:把src的内容追加到dest后面,相当于 dest +=
返回值:dest
char *strcat(char *dest, const char *src);
功能:比较两个字符串,根据字典序比较,谁在前面谁小
返回值:
s1 == s2 0
s1 > s2 正数
s1 < s2 负数
int strcmp(const char *s1, const char *s2);
功能:比较两块内存中的数据是否相等,按字节比较
返回值:
s1 == s2 0
s1 > s2 正数
s1 < s2 负数
int memcmp(const void *s1,const void *s2,size_t n)
char *str1 = "abc";
char *str2 = "abb";
int ret = memcmp(str1,str2,3);
printf("%d\n",ret);
功能:比较前n个字符
int strncmp(const char *s1, const char *s2, size_t n);
功能:src只追加n个字符到dest后面
char *strncat(char *dest, const char *src,size_t n);
功能:把src拷贝n个字符到dest
char *strncpy(char *dest,const char *src,size_t n);
#include <stdlib.h>
int atoi(const char)
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
练习:自己实现strlen、strcpy、strcmp、strcat四个函数。
#include <stdio.h>
#include <assert.h>
size_t str_len(const char* str)
{
assert(NULL != str);
const char* tmp = str;
while(*tmp) tmp++;
return tmp - str;
}
char* str_cpy(char* dest, const char* src)
{
assert(NULL != dest && NULL != src);
char* tmp = dest;
while(*tmp++ = *src++);
return dest;
}
char* str_cat(char *dest, const char *src)
{
assert(NULL != dest && NULL != src);
char* tmp = dest;
while(*tmp) tmp++;
while(*tmp++ = *src++);
return dest;
}
int str_cmp(const char *s1, const char *s2)
{
assert(NULL != s1 && NULL != s2);
while(*s1 && *s1 == *s2) s1++,s2++;
return *s1 - *s2;
}
int main(int argc,const char* argv[])
{
}
sprintf
字符串拼接
功能:把各类型的数据输出到str中(各种类型的数据合成字符串)
返回值:字符串的长度
int sprintf(char *str, const char *format,...)
char str[265] = "1234";
int num = 5678;
short num1 = 100;
sprintf(str,"%d",num);
//sprintf(str,"num=%d",num,num1); num=5678100;
printf("%s\n",str);//str = 5678;
for(int i = 0; i<str)
{
printf("%d ",str[i]);//53 54 55 56 变成了字符型
}
sscanf
字符串的解析(分解成各种类型的数据)
功能:从str中按照格式,读取数据
返回值:成功读取到的变量个数
int sscanf(const char *str,const char *format, ...);
const char* str = "1995 10 1";
int year,month,day;
sscanf(str,"%d %d %d %d",&year,&month,&day);
printf("%d %d %d\n",year,month,day);
输出缓冲区:
程序输入的数据并不能立即写入到"文件",而是先存储到缓冲区中,当满足一定条件时才会写入到"文件"中。
1、遇到\n后
2、当程序结束时
3、遇到输入语句
4、当输出缓冲区满4k时
5、手动刷新 fflush(stdout) 只能在Linux下使用
缓冲区机制时可以提高数据的读写速度,可以让高速的CPU与低速的输入输出设备之间协调工作。
输入缓冲区:
程序并不会立即获取到从键盘上输入的数据,而是当按下回车按键时,数据由终端写入到程序的输入缓冲区,scanf函数再从输入缓冲区中读取数据,最后赋值给变量
1、当读取的数据是整型或者是浮点型数据时,而缓冲区中的数据是字母或符号时,此时读取会失败,而且数据会残留在输入缓冲区,就会影响接下来所有数据的读取
解决方法:
根据返回值判断是否接收成功
int a,b,c;
while(3 > scanf("%d%d%d",&a,&b,&c))
{
printf("输入数据格式有误,请重新输入");
scanf("%*[^\n]");
scanf("%*c");
}
2、fgets可以指定读取size-1个字符,如果有多余的字符会残留在输入缓冲区中,多余的字符会被下一个接收
解决方法1:
fget(str,20,stdin);
int len = 0;
while(str[len])len++;
if('\n' != str[len-1])
{
scanf("%*[^\n]");//遇到任意字符,凡不是\n就丢弃(必须确定输入缓冲区中有垃圾数据才能使用)
scanf("%*c");//丢弃一个字符
}
解决方法2:
stdin->_IO_read_ptr = stdin->_IO_read_end;
//只能在Linux系统下使用
3、当先输入整型、浮点型数据,然后再输入字符、字符串时,会有一 个字符’\n’残留在输入缓冲区中
如果输出字符,会接收回车
如果字符串 应该使用scanf, gets会出错 需要scanf("%*c"); gets(str);
解决方法:scanf(" %c",&ch); 加个空格
复习:
堆内存和栈内存的区别:
是什么 谁管理 大小 使用 安全 优缺点:
堆内存的越界后果:
超过33页产生段错误
破坏了malloc的维护性信息,再次使用malloc/free会出错
脏数据
什么是内存泄漏,如何定位内存泄漏
由于业务逻辑出错或者粗心大意导致使用完毕的堆内存没有及时释放,
当再次需要时又只能重新申请堆内存,然后由没释放,长此以往导致可用的内存越来越少,系统就会越来越慢 直到系统崩溃,这种就叫内存泄漏。