专业的网站建设托管,网站开发最好用什么软件,如何自己开一个平台,搭建网站 网页目录 一、字符串的引入和注意事项
1.1 字符串定义的几种方式#xff1a;
1.2 定义字符串的方法一和方法二的区别#xff1a;
1.3 字符串输出的几种方式#xff1a; 1.3.1 循环下标法遍历输出字符串#xff1a; 1.3.2 转义字符%s输出字符串#xff1a; 1.3.3 使用puts函…目录 一、字符串的引入和注意事项
1.1 字符串定义的几种方式
1.2 定义字符串的方法一和方法二的区别
1.3 字符串输出的几种方式 1.3.1 循环下标法遍历输出字符串 1.3.2 转义字符%s输出字符串 1.3.3 使用puts函数输出字符串
1.4 字符串初始总结
二、字符串的内存存放方式及结束标志
2.1 回忆如何计算数组的大小及数组元素的个数
2.2 字符串和字符数组的存储方式区别
三、sizeof和strlen区别很重要
3.1 sizeof和strlen分别计算字符串变量
3.2 sizeof和strlen分别计算字符串常量
四、malloc动态开辟内存空间
4.1 malloc动态开辟内存空间函数引入 4.1.1 malloc函数认知和函数原型 4.1.2 使用malloc动态开辟一快内存空间
4.2 strcpy函数引入 4.2.1 strcpy函数原型 4.2.2 strcpy函数应用
4.3 free函数引入 4.3.1 free函数原型和作用 4.3.2 free函数应用
4.3 realloc扩容函数引入 4.3.1 为什么要用realloc扩容函数 4.3.2 realloc函数原型和作用 4.3.3 realloc函数应用
4.4 memset清理内存空间函数引入 4.4.1 memset函数原型 4.4.2 memset函数应用
4.5 malloc动态开辟内存总结
五、字符串常用API
5.1 输出字符串 5.1.1 puts函数输出字符串 5.1.2 使用printf函数输出字符串
5.2 输入字符串 5.2.1 使用scanf函数输入字符串 5.2.2 gets函数输入字符串
5.3 字符串拷贝函数strcpy 5.3.1 strcpy函数原型 5.3.2 字符串拷贝函数strcpy应用 5.3.3 自己实现字符串拷贝函数strcpy
5.4 strncpy部分字符拷贝函数 5.4.1 strncpy函数原型和作用 5.4.2 strncpy函数应用 5.4.3 自己实现部分字符串拷贝函数strncpy:
5.5 assert断言函数 5.5.1 assert断言函数认知 5.5.2 assert断言函数原型 5.5.3 assert断言函数应用
5.6 strcat字符串拼接函数 5.6.1 strcat函数原型和作用 5.6.2 strcat字符串拼接函数应用 5.6.3 自己实现strcat字符串拼接函数
5.7 strcmp字符串比较函数 5.7.1 strcmp函数原型和作用 5.7.2 strcmp函数应用 5.7.3 自己实现字符串比较函数strcmp:
5.8 strncmp字符串比较函数 5.8.1 strncmp函数原型和作用 5.8.2 strncmp函数应用 一、字符串的引入和注意事项 字符串就是字符数组虽然我不想这样说
1.1 字符串定义的几种方式 我们都知道整型数组该如何定义
#include stdio.hint main()
{int arr[] {1,2,3,4,5}; //定义一个整型数组for(int i0; i5; i){printf(%d ,arr[i]);}return 0;
}
/*
E:\code\一阶段C语言\第七章_字符串gcc demo.cE:\code\一阶段C语言\第七章_字符串a.exe
1 2 3 4 5
*/ 那字符串和整型数组一个道理
#include stdio.hint main()
{char cdata[] {h,e,l,l,o}; //定义一个字符数组for(int i0; i5; i){printf(%c,cdata[i]);}return 0;
}
/*
E:\code\一阶段C语言\第七章_字符串gcc demo.cE:\code\一阶段C语言\第七章_字符串a.exe
hello
*/ 上面这种字符串定义方式并不好用太麻烦了那该如何改进呢 定义字符串方法一
#include stdio.hint main()
{char cdata[] hello; //定义一个字符串方法一for(int i0; i5; i){printf(%c,cdata[i]);}return 0;
}
/*
E:\code\一阶段C语言\第七章_字符串gcc demo.cE:\code\一阶段C语言\第七章_字符串a.exe
hello
*/ 一般情况下我们这样定义一个字符串 定义字符串方法二
/*字符串的名字是一个地址是字符串的首地址我们可以定义一个指针来保存字符串的首地址
*/
#include stdio.hint main()
{char *pcdata hello; //定义一个字符串方法二for(int i0; i5; i){printf(%c,*(pcdatai));}return 0;
}
/*
E:\code\一阶段C语言\第七章_字符串gcc demo.cE:\code\一阶段C语言\第七章_字符串a.exe
hello
*/ 1.2 定义字符串的方法一和方法二的区别 方法一是字符串变量里面的每一个字符都是可以修改的
#include stdio.hint main()
{char cdata[] hello;printf(修改前\n);for(int i0; i5; i){printf(%c,cdata[i]); //字符串修改前打印输出}cdata[3] m;printf(\n修改后\n);for(int i0; i5; i){printf(%c,cdata[i]); //字符串修改后打印输出}return 0;
}
/*
E:\code\一阶段C语言\第七章_字符串gcc demo.cE:\code\一阶段C语言\第七章_字符串a.exe
修改前
hello
修改后
helmo
*/ 方法二是字符串常量里面的每一个字符不允许被修改
#include stdio.hint main()
{char *pcdata hello;printf(修改前\n);for(int i0; i5; i){printf(%c,*(pcdatai));}*pcdata m; printf(修改后\n);for(int i0; i5; i){printf(%c,*(pcdatai));}return 0;
}
/*
E:\code\一阶段C语言\第七章_字符串gcc demo.cE:\code\一阶段C语言\第七章_字符串a.exe
修改前
hello
*/ 我们可以看到程序编译没有问题但是程序执行到第12行的时候卡了一下就退出了其实这里是发生了一个段错误
/*
E:\code\一阶段C语言\第七章_字符串gcc demo.c -gE:\code\一阶段C语言\第七章_字符串gdb a.exe
GNU gdb (GDB) 8.1
Copyright (C) 2018 Free Software Foundation, Inc.
License GPLv3: GNU GPL version 3 or later http://gnu.org/licenses/gpl.html
This is free software: you are free to change and redistribute it.
There is NO WARRANTY, to the extent permitted by law. Type show copying
and show warranty for details.
This GDB was configured as x86_64-w64-mingw32.
Type show configuration for configuration details.
For bug reporting instructions, please see:
http://www.gnu.org/software/gdb/bugs/.
Find the GDB manual and other documentation resources online at:
http://www.gnu.org/software/gdb/documentation/.
For help, type help.
Type apropos word to search for commands related to word...
Reading symbols from a.exe...done.
(gdb) r
Starting program: E:\code\C\_\a.exe
[New Thread 107412.0x19efc]
[New Thread 107412.0x18a5c]
修改前
hello
Thread 1 received signal SIGSEGV, Segmentation fault.
0x00000000004015a4 in main () at demo.c:12
12 *pcdata m;
(gdb)
*/ 1.3 字符串输出的几种方式
1.3.1 循环下标法遍历输出字符串 上面我们对字符串的遍历输出全部都是使用循环访问下标的方式输出的但是这种方法太蠢了
#include stdio.hint main()
{char cdata[] hello;char *pcdata hello;for(int i0; i5; i){printf(%c,cdata[i]);}putchar(\n);for(int i0; i5; i){printf(%c,*(pcdatai));}return 0;
}
/*
E:\code\一阶段C语言\第七章_字符串gcc demo.c -gE:\code\一阶段C语言\第七章_字符串a.exe
hello
hello
*/ 1.3.2 转义字符%s输出字符串
/*在printf的时候使用转义字符%s输出字符串
*/
#include stdio.hint main()
{char cdata[] hello;char *pcdata hello;printf(%s\n,cdata); //这里要的是一个地址printf(%s,pcdata);return 0;
}
/*
E:\code\一阶段C语言\第七章_字符串gcc demo.c -gE:\code\一阶段C语言\第七章_字符串a.exe
hello
hello
*/ 1.3.3 使用puts函数输出字符串
/*使用puts函数也可以输出字符串puts的意思本来就是Output String
*/
#include stdio.hint main()
{char cdata[] hello;char *pcdata hello;puts(cdata); //puts后面跟的是一个地址puts(pcdata); //puts后面跟的是一个地址return 0;
}
/*
E:\code\一阶段C语言\第七章_字符串gcc demo.c -gE:\code\一阶段C语言\第七章_字符串a.exe
hello
hello
*/ 1.4 字符串初始总结 定义字符串的几种方式
/*定义一个字符串的几种方式
*/
char cdata[] {h,e,l,l,o};
char cdata2[] hello;
char *pcdata hello; 输出字符串的几种方式
/*循环遍历输出字符串蠢*/
char cdata[] hello;for(int i0; i5; i){printf(%c,cdata[i]);
}
/*转义字符%s输出字符串*/
char cdata[] hello;printf(%s,cdata);
/*使用puts函数输出字符串*/
char *pcdata hello;puts(pcdata); 字符串变量和字符串常量区别
char cdata[] hello;
/*字符串变量里面的每一个字符是可以修改的*/char *pcdata hello;
/*字符串常量里面的每一个字符不允许修改*/ 注意对指针的操作 指针可以保存地址对字符串常量的的地址空间访问但对野指针的内存空间操作不行
#include stdio.hint main()
{char *p; //野指针并没有明确的内存指向危险⚠*p c;printf(%c,*p);return 0;
}
/*
E:\code\一阶段C语言\第七章_字符串gcc demo.c -gE:\code\一阶段C语言\第七章_字符串gdb a.exe
GNU gdb (GDB) 8.1
Copyright (C) 2018 Free Software Foundation, Inc.
License GPLv3: GNU GPL version 3 or later http://gnu.org/licenses/gpl.html
This is free software: you are free to change and redistribute it.
There is NO WARRANTY, to the extent permitted by law. Type show copying
and show warranty for details.
This GDB was configured as x86_64-w64-mingw32.
Type show configuration for configuration details.
For bug reporting instructions, please see:
http://www.gnu.org/software/gdb/bugs/.
Find the GDB manual and other documentation resources online at:
http://www.gnu.org/software/gdb/documentation/.
For help, type help.
Type apropos word to search for commands related to word...
Reading symbols from a.exe...done.
(gdb) r
Starting program: E:\code\C\_\a.exe
[New Thread 108284.0x1a868]
[New Thread 108284.0x1aac4]Thread 1 received signal SIGSEGV, Segmentation fault.
0x0000000000401561 in main () at demo.c:7
7 *p c;
*/ 二、字符串的内存存放方式及结束标志
2.1 回忆如何计算数组的大小及数组元素的个数
/*计算一个数组的大小和数组元素的个数
*/
#include stdio.hint main()
{int data[] {1,2,3,4,5};printf(数组的大小是%d\n,sizeof(data));int len sizeof(data) / sizeof(data[0]);printf(数组元素个数len %d\n,len);return 0;
}
/*
E:\code\一阶段C语言\第七章_字符串gcc demo_len.cE:\code\一阶段C语言\第七章_字符串a.exe
数组的大小是20
数组元素个数len 5
*/ 2.2 字符串和字符数组的存储方式区别
/*分别计算字符数组和字符串观察有什么区别
*/
#include stdio.hint main()
{char cdata[5] {h,e,l,l,o}; //定义一个字符数组char cdata2[] hello; //定义一个字符串int len sizeof(cdata) / sizeof(cdata[0]);printf(len %d\n,len);len sizeof(cdata2) / sizeof(cdata2[0]);printf(len %d\n,len);return 0;
}
/*
E:\code\一阶段C语言\第七章_字符串gcc demo_len.cE:\code\一阶段C语言\第七章_字符串a.exe
len 5
len 6
*/ 我们可以看到字符数组的长度是5而字符串的长度是6 是因为字符串后面多出了一个\0,\0代表字符串的结束标志
/*在定义或者声明字符数组的时候需要注意在后面加上一个\0,如果编译器优化不到位就会出现乱码的情况⚠
*/
#include stdio.hint main()
{char cdata[6] {h,e,l,l,o,\0};return 0;
}
/*字符串的结束标志\0,这个东西非常重要比如在后面的关于字符串的各种API里面都是在找\0*/ #include string.h 三、sizeof和strlen区别很重要
3.1 sizeof和strlen分别计算字符串变量
#include stdio.h
#include string.hint main()
{char cdata[] hello;printf(sizeof :%d\n,sizeof(cdata)); //sizeof计算字符串的所有字符printf(strlen :%d\n,strlen(cdata)); //strlen计算字符串的有效字符return 0;
}
/*
E:\code\一阶段C语言\第七章_字符串gcc demo_sizeof_strlen.cE:\code\一阶段C语言\第七章_字符串a.exe
sizeof :6
strlen :5
*/ 我们看到sizeof的时候是6,是因为字符串的结束标志\0也是一个字符 而strlen的时候是5,是因为strlen是计算字符串的有效字符的长度
/*我们知道sizeof是计算整个字符串的大小那我把字符串改成128那sizeof的结果是多少呢
*/
#include stdio.h
#include string.hint main()
{char cdata[128] hello;printf(sizeof :%d\n,sizeof(cdata));printf(strlen :%d\n,strlen(cdata));return 0;
}
/*
E:\code\一阶段C语言\第七章_字符串gcc demo_sizeof_strlen.cE:\code\一阶段C语言\第七章_字符串a.exe
sizeof :128
strlen :5
*/ 可以看到sizeof是128sizeof是计算整个字符串的大小除了有效字符外其他的系统会自动补\0 该用sizeof的时候用sizeof,该用strlen的时候用strlen,如果该用sizeof的时候用了strlen那么数据就不对了 3.2 sizeof和strlen分别计算字符串常量
#include stdio.h
#include string.hvoid test()
{}int main()
{void (*ptest)() test; //定义一个函数指针变量char *p hello;//p是一个char *型用sizeof来计算的时候得出的是计算机用多少个个字节来表示一个地址printf(sizeof p :%d\n,sizeof(p)); printf(sizeof char* :%d\n,sizeof(char *));printf(sizeof int * :%d\n,sizeof(int *));printf(sizeof ptest :%d\n,sizeof(ptest));printf(sizeof char :%d\n,sizeof(char));printf(strlen p :%d\n,strlen(p));return 0;
}
/*
E:\code\一阶段C语言\第七章_字符串gcc demo_sizeof_strlen.cE:\code\一阶段C语言\第七章_字符串a.exe
sizeof p :8
sizeof char* :8
sizeof int * :8
sizeof ptest :8
sizeof char :1
strlen p :5
*/ sizeof字符串常量的时候表示操作系统用多少个字节来表示一个地址 strlen字符串常量的时候仍然是代表字符串的有效长度 四、malloc动态开辟内存空间
4.1 malloc动态开辟内存空间函数引入
4.1.1 malloc函数认知和函数原型 通常我们定义数组或者字符数组的时候就已经把内存地址定好了例如
int data[] {1,2,3,4,5}; //定义一个整型数组
char cdata[] {h,e,l,l,o}; //定义一个字符数组 那么现在我有一个需求我不希望一开始就耗费这么大的空间我想按需求开辟内存空间引入动态开辟内存空间malloc函数 malloc函数就是我们在堆上面动态的开辟内存空间它跟以前我们数组占用的使用的内存空间是不一样的以前我们数组都是在栈区那么堆是malloc对应的内存空间
/*malloc函数原型*/void* malloc(size_t size)
/*分配所需的内存空间并返回一个指向它的指针*/ 4.1.2 使用malloc动态开辟一快内存空间
/*我们之前写过一个例子对这个p进行赋值的时候会产生一个段错误p是一个野指针对野指针赋值我们会看到犯错如果不会犯错程序中end会执行你会看到end根本就不会执行p没有具体的指向哪个内存空间
*/
#include stdio.hint main()
{char *p; //野指针*p c;puts(end);return 0;
}
/*
E:\code\一阶段C语言\第七章_字符串gcc demo_malloc.c -gE:\code\一阶段C语言\第七章_字符串gdb a.exe
GNU gdb (GDB) 8.1
Copyright (C) 2018 Free Software Foundation, Inc.
License GPLv3: GNU GPL version 3 or later http://gnu.org/licenses/gpl.html
This is free software: you are free to change and redistribute it.
There is NO WARRANTY, to the extent permitted by law. Type show copying
and show warranty for details.
This GDB was configured as x86_64-w64-mingw32.
Type show configuration for configuration details.
For bug reporting instructions, please see:
http://www.gnu.org/software/gdb/bugs/.
Find the GDB manual and other documentation resources online at:
http://www.gnu.org/software/gdb/documentation/.
For help, type help.
Type apropos word to search for commands related to word...
Reading symbols from a.exe...done.
(gdb) r
Starting program: E:\code\C\_\a.exe
[New Thread 107868.0x162c0]
[New Thread 107868.0x1b344]Thread 1 received signal SIGSEGV, Segmentation fault.
0x0000000000401561 in main () at demo_malloc.c:7
7 *p c;
*/ 我们使用malloc函数动态开辟内存空间用p来承接它
/*malloc动态开辟一块内存空间
*/
#include stdio.h
#include stdlib.hint main()
{char *p;p (char *)malloc(1); //p现在就有了具体的内存指向*p c;printf(%c\n,*p);puts(end);return 0;
}
/*
E:\code\一阶段C语言\第七章_字符串gcc demo_malloc.c -gE:\code\一阶段C语言\第七章_字符串a.exe
c
end
*/ 现在的p就不是一个野指针了p有了具体的内存指向 程序中为什么需要将malloc返回的地址强制转换成char *型呢因为malloc函数返回的地址是一个void *型如果想用p来承接malloc返回的内存地址的话必须强制转换成char *型 4.2 strcpy函数引入
4.2.1 strcpy函数原型
/*strcpy函数原型*/
char* strcpy(char *dest, const char *src)
/*字符串拷贝函数strcpy(拷贝到哪里去从哪里拷贝);
*/
4.2.2 strcpy函数应用 我们可以开辟一个内存空间当然也可以开辟多个内存空间
#include stdio.hint main()
{char *p; //野指针p (char *)malloc(1);*p c;p (char *)malloc(12); //开辟12个内存空间return 0;
} 这里开辟了12个内存空间仍然用p来承接。这个时候就需要往里面放数据了于是引入一个函数strcpy字符串拷贝函数
#include stdio.h
#include stdlib.h
#include string.hint main()
{char *p; //野指针p (char *)malloc(1);*p c;p (char *)malloc(12);strcpy(p,chenlichen);puts(p);return 0;
}
/*
E:\code\一阶段C语言\第七章_字符串gcc demo_malloc.c -gE:\code\一阶段C语言\第七章_字符串a.exe
chenlichen
*/
⚠这边其实存在一个很严重的问题 刚开始p指向的是你开辟的一个内存空间但是你又开辟了12字节内存空间也让p指向了它此时p就会和之前开辟的那一块内存空间断开并指向新开辟的12字节内存空间此时那一块和p断开的内存就成了悬挂无用的内存了已经找不到这个地址了空闲在这了。像这种空闲在这的内存我们通常需要通过free将其释放 因为malloc它在堆上面开辟内存空间数组和普通的变量是在栈开辟内存空间在函数调用结束以后它会清理栈里面的数据回收内存那堆只有到程序结束以后内存才会释放有一个风险如果你是一个死循环不断地malloc,有可能会耗尽你计算机上堆的内存资源所以需要通过free将其释放掉 4.3 free函数引入
4.3.1 free函数原型和作用
/*free函数原型*/
void free(void *ptr); free函数作用释放之前调用callocmalloc和realloc所分配的内存空间释放无用内存防止内存泄漏防止悬挂指针悬挂指针是野指针的一种 4.3.2 free函数应用
#include stdio.h
#include stdlib.h
#include string.hint main()
{char *p; //野指针p (char *)malloc(1);*p c;free(p); //释放无用内存放置内存泄露p NULL; //尽量不要悬挂指针p (char *)malloc(12);strcpy(p,chenlichen);puts(p);return 0;
} free释放掉无用内存后p重新变成了野指针一般让p NULL尽量不要悬挂指针 4.3 realloc扩容函数引入
4.3.1 为什么要用realloc扩容函数
#include stdio.h
#include stdlib.h
#include string.hint main()
{char *p; //野指针p (char *)malloc(12);strcpy(p,chenlichenshuai123456789987654321);puts(p);return 0;
} 比如说现在有这么多的数据需要放到内存空间中而上面malloc只开辟了12个字节的内存空间如果这么多数据需要放到里面的话是不行的会发生越界导致程序崩溃,这个时候就可以使用realloc扩容函数来解决
4.3.2 realloc函数原型和作用
/*realloc函数原型*/
void* realloc(void *ptr, size_t size);
/*字符串扩容函数realloc(原本扩容地址要继续增大多少);
*/ realloc函数作用尝试重新调整之前调用malloc和calloc所分配的ptr所指向的内存块大小
4.3.3 realloc函数应用
#include stdio.h
#include stdlib.h
#include string.hint main()
{char *p; //野指针p (char *)malloc(12);printf(扩容前地址%x\n,p);int len strlen(chenlichenshuai123456789987654321);//计算字符串的有效字符大小int newLen len - 12 1; //实际扩容大小 总长度 - 原来动态开辟的12个 结束标志\0realloc(p,newLen);printf(扩容后地址%x\n,p);strcpy(p,chenlichenshuai123456789987654321);puts(p);return 0;
}
/*
E:\code\一阶段C语言\第七章_字符串gcc demo_malloc.cE:\code\一阶段C语言\第七章_字符串a.exe
扩容前地址685920
扩容后地址685920
chenlichenshuai123456789987654321
*/ 扩容前和扩容后的地址是一样的 4.4 memset清理内存空间函数引入
4.4.1 memset函数原型
/*memset函数原型*/
void* memset(void *str, int c, size_t n);
/*void* memset(新开辟的内存地址要初始化的内容内存大小);
*/
4.4.2 memset函数应用
#include stdio.h
#include stdlib.h
#include string.hint main()
{char *p; //野指针p (char *)malloc(12);memset(p,\0,12); //把刚开始动态开辟的内存空间全部初始化成\0printf(扩容前地址%x\n,p);int len strlen(chenlichenshuai123456789987654321);//计算字符串的有效字符大小int newLen len - 12 1; //实际扩容大小 总长度 - 原来动态开辟的12个 结束标志\0realloc(p,newLen);printf(扩容后地址%x\n,p);strcpy(p,chenlichenshuai123456789987654321);puts(p);return 0;
}
/*
E:\code\一阶段C语言\第七章_字符串gcc demo_malloc.cE:\code\一阶段C语言\第七章_字符串a.exe
扩容前地址685920
扩容后地址685920
chenlichenshuai123456789987654321
*/ 4.5 malloc动态开辟内存总结
#include stdio.h
#include stdlib.h
#include string.hint main()
{char *p; //野指针p (char *)malloc(1); //现在有了具体的内存指向*p c;printf(%c\n,*p);free(p); //释放无用内存放置内存泄漏p NULL; //尽量不要悬挂指针p (char *)malloc(12); //使用malloc函数动态开辟了12个内存空间用p承接if(p NULL){ //判断malloc是否动态开辟成功printf(malloc erroe!\n);}memset(p,\0,12); //新开辟的内存空间全部初始化成\0printf(扩容前地址%x\n,p);int len strlen(chenlichenshuai123456789987654321);int newLen len - 12 1;realloc(p,newLen); //扩容内存printf(扩容后地址%x\n,p);strcpy(p,chenlichenshuai123456789987654321);puts(p);return 0;
}
/*
E:\code\一阶段C语言\第七章_字符串gcc demo_malloc.cE:\code\一阶段C语言\第七章_字符串a.exe
c
扩容前地址1b13e0
扩容后地址1b13e0
chenlichenshuai123456789987654321
*/ 五、字符串常用API
5.1 输出字符串
5.1.1 puts函数输出字符串
/*使用puts函数输出字符串
*/
#include stdio.hint main()
{char cdata[] chenlichen shaui;char *pchar chenlichen shuai;puts(cdata);puts(pchar);return 0;
}
/*
E:\code\一阶段C语言\第七章_字符串gcc demo_puts_gets.cE:\code\一阶段C语言\第七章_字符串a.exe
chenlichen shaui
chenlichen shuai
*/
5.1.2 使用printf函数输出字符串
/*在printf函数的时候利用转义字符%s输出字符串
*/
#include stdio.hint main()
{char cdata[] chenlichen shuai;char *pchar chenlichen shaui;printf(%s\n,cdata);printf(%s\n,pchar);return 0;
}
/*
E:\code\一阶段C语言\第七章_字符串gcc demo_puts_gets.cE:\code\一阶段C语言\第七章_字符串a.exe
chenlichen shuai
chenlichen shaui
*/ 5.2 输入字符串
5.2.1 使用scanf函数输入字符串
/*在scanf函数的时候利用转义字符%s输入字符串
*/
#include stdio.hint main()
{char cdata[128] {\0};puts(请输入字符串);scanf(%s,cdata);puts(cdata);return 0;
}
/*
E:\code\一阶段C语言\第七章_字符串gcc demo_puts_gets.cE:\code\一阶段C语言\第七章_字符串a.exe
请输入字符串
chenlichenshuai
chenlichenshuai
*/
5.2.2 gets函数输入字符串
/*gets函数原型*/
char* gets(char *str); 因为本函数可以无限读取易发生溢出。如果溢出多出来的字符将被写入到堆栈中这就覆盖了堆栈原先的内容破坏一个或多个不相关变量的值
/*使用gets函数输入字符串
*/
#include stdio.hint main()
{char cdata[128] {\0};puts(请输入字符串);gets(cdata);puts(cdata);return 0;
}
/*
E:\code\一阶段C语言\第七章_字符串gcc demo_puts_gets.cE:\code\一阶段C语言\第七章_字符串a.exe
请输入字符串
chenlichenshuai
chenlichenshuai
*/ 5.3 字符串拷贝函数strcpy
5.3.1 strcpy函数原型
/*strcpy函数原型*/
char* strcpy(char *dest, const char *src)
/* 字符串拷贝函数strcpy(拷贝到哪里去从哪里拷贝);*/
5.3.2 字符串拷贝函数strcpy应用
#include stdio.h
#include string.hint main()
{char str[128] {\0};char *p chenlichen handsome;strcpy(str,p);puts(str);return 0;
}
/*程序运行结果
E:\code\一阶段C语言\第七章_字符串gcc demo_strcpy.cE:\code\一阶段C语言\第七章_字符串a.exe
chenlichen handsome
*/
5.3.3 自己实现字符串拷贝函数strcpy
/*第一种自己实现字符串拷贝函数
*/
#include stdio.hchar* myStrcpy(char *dest, char *src)
{if(dest NULL || src NULL){return NULL;}char *bak dest;while(*src ! \0){*dest *src;dest;src;}*dest \0;return bak;
}int main()
{char str[128] {\0};char *p chenlichen handsome;myStrcpy(str,p);puts(str);return 0;
}
/*
E:\code\一阶段C语言\第七章_字符串gcc demo_strcpy.cE:\code\一阶段C语言\第七章_字符串a.exe
chenlichen handsome
*/
/*第二种自己实现字符串拷贝函数
*/
#include stdio.hchar* myStrcpy2(char *dest, char *src)
{if(dest NULL || src NULL){return NULL;}char *bak dest;while(*src ! \0){*dest *src;}*dest \0;return bak;
}int main()
{char str[128] {\0};char *p chenlichen handsome;myStrcpy2(str, p);puts(str);return 0;
}
/*
E:\code\一阶段C语言\第七章_字符串gcc demo_strcpy.cE:\code\一阶段C语言\第七章_字符串a.exe
chenlichen handsome
*/
/*第三种自己实现字符串拷贝函数
*/
#include stdio.hchar* myStrcpy3(char *dest, char *src)
{if(dest NULL || src NULL){return NULL;}char *bak dest;while((*dest *src) ! \0);*dest \0;return bak
}int main()
{char str[128] {\0};char *p chenlichen handsome;myStrcpy3(str, p);puts(str);return 0;
}
/*
E:\code\一阶段C语言\第七章_字符串gcc demo_strcpy.cE:\code\一阶段C语言\第七章_字符串a.exe
chenlichen handsome
*/ 5.4 strncpy部分字符拷贝函数
5.4.1 strncpy函数原型和作用
/*strncpy函数原型*/
char* strncpy(char *dest, const char *src, int n);
/* strncpy(拷贝到哪里去从哪里拷贝要拷贝多少); strncpy函数作用表示把src所指向的字符串中以src地址开始的前n个字节复制到dest所指的数组中并返回被复制后的dest*/
5.4.2 strncpy函数应用
#include stdio.h
#include string.hint main()
{char str[128] {\0};char *p chenlichen handsome;strncpy(str, p, 6);puts(str);return 0;
}
/*
E:\code\一阶段C语言\第七章_字符串gcc demo_strncpy.cE:\code\一阶段C语言\第七章_字符串a.exe
chenli
*/
5.4.3 自己实现部分字符串拷贝函数strncpy:
#include stdio.h
#include string.hchar* myStrncpy(char *dest, char *src, int count)
{if(dest NULL || src NULL){return NULL;}char *bak dest;while(*src ! \0 count0){*dest *src;count--;}if(count 0){while(count 0){count--;*dest \0;}return dest;}*dest \0;return bak;
}int main()
{char str[128] {\0};char *p chenlichen handsome;myStrncpy(str, p, 6);puts(str);return 0;
}
/*
E:\code\一阶段C语言\第七章_字符串gcc demo_strncpy.cE:\code\一阶段C语言\第七章_字符串a.exe
chenli
*/ 5.5 assert断言函数
5.5.1 assert断言函数认知
/*assert 宏的原型定义在 assert.h 中其作用是如果它的条件返回错误则终止程序执行*/
#include assert.h assert 的作用是现计算表达式 expression 如果其值为假即为0那么它先向 stderr 打印一条出错信息,然后通过调用 abort 来终止程序运行。 使用 assert 的缺点是频繁的调用会极大的影响程序的性能增加额外的开销。
5.5.2 assert断言函数原型
/*assert函数原型*/
void assert(int expression);
5.5.3 assert断言函数应用
#include stdio.h
#include assert.hchar* myStrcpy(char *dest, char *src)
{assert(dest ! NULL src ! NULL);//断言函数char *bak dest;while(*src ! \0){*dest *src;}*dest \0;return bak;
}int main()
{char str[128] {\0};char *p chenlichen shuai;myStrcpy(str,p);puts(str);return 0;
}
/*
E:\code\一阶段C语言\第七章_字符串gcc demo_assert.cE:\code\一阶段C语言\第七章_字符串a.exe
chenlichen shuai
*/ 5.6 strcat字符串拼接函数
5.6.1 strcat函数原型和作用
/*strcat函数原型*/
char* strcat(char *dest, const char *src);
/*strcat(拼接到哪里去从哪里拼接);strcat作用把src所指向的字符串包括“\0”复制到dest所指向的字符串后面删除*dest原来末尾 的“\0”。要保证*dest足够长以容纳被复制进来的*src。*src中原有的字符不变。返回指向dest的指针。
*/
5.6.2 strcat字符串拼接函数应用
#include stdio.h
#include string.hint main()
{char str[128] chenlichen;char *p handsome;strcat(str,p); //strcat(拼接到哪里去从哪里拼接);puts(str);return 0;
}
/*
E:\code\一阶段C语言\第七章_字符串gcc demo_strcat.cE:\code\一阶段C语言\第七章_字符串a.exe
chenlichen handsome
*/
5.6.3 自己实现strcat字符串拼接函数
/*自己实现字符串拼接函数方法一
*/
#include stdio.h
#include assert.hchar* myStrcat(char *dest, char *src)
{assert(dest ! NULL src ! NULL);char *bak dest;while(*dest ! \0){dest;}while(*src ! \0){*dest *src;}*dest \0;return bak;
}int main()
{char str[128] chenlichen;char *p handsome;myStrcat(str,p);puts(str);return 0;
}
/*
E:\code\一阶段C语言\第七章_字符串gcc demo_strcat.cE:\code\一阶段C语言\第七章_字符串a.exe
chenlichen handsome
*/
/*自己实现字符串拼接函数方法二
*/
#include stdio.h
#include assert.h
#include string.hchar* myStrcat2(char *dest, char *src)
{char *bak dest;strcpy(deststrlen(dest),src); //字符串拷贝函数strcpy(拷贝到哪里去从哪里拷贝);return bak;
}int main()
{char str[128] chenlichen;char *p handsome;myStrcat2(str,p);puts(str);return 0;
}
/*
E:\code\一阶段C语言\第七章_字符串gcc demo_strcat.cE:\code\一阶段C语言\第七章_字符串a.exe
chenlichen handsome
*/
/*自己实现字符串拼接函数方法三
*/
#include stdio.h
#include assert.h
#include string.hchar* myStrcat3(char *dest, char *src)
{assert(dest ! NULL src ! NULL);char *bak dest;for( ; *dest!\0; dest);while((*dest *src) ! \0);*dest \0;return bak;
}int main()
{char str[128] chenlichen;char *p handsome;myStrcat3(str,p);puts(str);return 0;
}
/*
E:\code\一阶段C语言\第七章_字符串gcc demo_strcat.cE:\code\一阶段C语言\第七章_字符串a.exe
chenlichen handsome
*/ 5.7 strcmp字符串比较函数
5.7.1 strcmp函数原型和作用
/*strcmp函数原型*/
int strcmp(const char *str1, const char *str2);
/*strcmp作用若str1str2则返回零若str1str2则返回负数若str1str2则返回正数
*/
5.7.2 strcmp函数应用
/*如果两个字符串一样则ret 0;
*/
#include stdio.h
#include string.hint main()
{char *str1 chenlichen;char *str2 chenlichen;int ret;ret strcmp(str1,str2);if(ret 0){puts(两个字符串一样);}printf(ret %d\n,ret);return 0;
}
/*
E:\code\一阶段C语言\第七章_字符串gcc demo_strcmp.cE:\code\一阶段C语言\第七章_字符串a.exe
两个字符串一样
ret 0
*/
/*如果str1 str2则ret -1;
*/
#include stdio.h
#include string.hint main()
{char *str1 chenlichena;char *str2 chenlichenb;int ret;ret strcmp(str1,str2);if(str1 str2){puts(两个字符串一样);}printf(ret %d\n,ret);return 0;
}
/*
E:\code\一阶段C语言\第七章_字符串gcc demo_strcmp.cE:\code\一阶段C语言\第七章_字符串a.exe
ret -1
*/
/*如果str1 str2则ret 1;
*/
#include stdio.h
#include string.hint main()
{char *str1 chenlichenb;char *str2 chenlichena;int ret;ret strcmp(str1,str2);if(str1 str2){puts(两个字符串一样);}printf(ret %d\n,ret);return 0;
}
/*
E:\code\一阶段C语言\第七章_字符串gcc demo_strcmp.cE:\code\一阶段C语言\第七章_字符串a.exe
ret 1
*/
5.7.3 自己实现字符串比较函数strcmp:
/*自己实现字符串比较函数strcmp;
*/
#include stdio.hint myStrcmp(char *str1, char *str2)
{int ret 0;int n_str1 0;int n_str2 0;char *bakstr1 str1;char *bakstr2 str2;while(*str1 ! \0 *str2 ! \0 (*str1 *str2)){str1;str2;}if(*str1 || *str2){str1 bakstr1;str2 bakstr2;while(*str1 ! \0){n_str1 n_str1 *str1;}while(*str2 ! \0){n_str2 n_str2 *str2;}}ret n_str1 - n_str2;if(ret 0){ret -1;}if(ret 0){ret 1;}return ret;
}int main()
{char *str1 chbenlichena;char *str2 chaenlichenb;int ret;ret myStrcmp(str1,str2);if(ret 0){puts(两个字符串一样);}printf(ret %d\n,ret);return 0;
}
/*
E:\code\一阶段C语言\第七章_字符串gcc demo_strcmp.cE:\code\一阶段C语言\第七章_字符串a.exe
两个字符串一样
ret 0
*/ 5.8 strncmp字符串比较函数
5.8.1 strncmp函数原型和作用
/*strncmp函数原型*/
int strncmp(const char *str1, const char *str2, size_t n);
/*作用功能是把 str1 和 str2 进行比较最多比较前 n 个字节若str1与str2的前n个字符相同则返回0若str1大于str2则返回大于0的值若str1小于str2则返回小于0的值。
*/
5.8.2 strncmp函数应用
/*若两个字符串前6个字符一样则返回0
*/
#include stdio.h
#include string.hint main()
{char *str1 chenlichen;char *str2 chenlichen;int ret;ret strncmp(str1,str2,6);if(ret 0){puts(两个字符串前面几个字符一样);}printf(ret %d\n,ret);return 0;
}
/*
E:\code\一阶段C语言\第七章_字符串gcc demo_strncmp.cE:\code\一阶段C语言\第七章_字符串a.exe
两个字符串前面几个字符一样
ret 0
*/
/*若str1前6个字符 str2前6个字符则返回-1
*/
#include stdio.h
#include string.hint main()
{char *str1 achenlichen;char *str2 bchenlichen;int ret;ret strncmp(str1,str2,6);if(ret 0){puts(两个字符串前几个字符一样);}printf(ret %d\n,ret);return 0;
}
/*
E:\code\一阶段C语言\第七章_字符串gcc demo_strncmp.cE:\code\一阶段C语言\第七章_字符串a.exe
ret -1
*/
/*若str1前6个字符 str2前6个字符则返回1
*/
#include stdio.h
#include string.hint main()
{char *str1 bchenlichen;char *str2 achenlichen;int ret;ret strncmp(str1,str2,6);if(ret 0){puts(两个字符串前几个字符一样);}printf(ret %d\n,ret);return 0;
}
/*
E:\code\一阶段C语言\第七章_字符串gcc demo_strncmp.cE:\code\一阶段C语言\第七章_字符串a.exe
ret 1
*/