涉及到的知识点有:
1、C语言库函数、字符输入函数:gets和fgets、字符输出函数:puts和fputs、
求字符串长度函数strlen、字符串追加函数strcat、字符串有限追加函数strncat、字符串比较函数strcmp、
字符串有限比较函数strcmp、字符串拷贝函数strcpy、字符串有限拷贝函数strncpy、
格式化字符串函数sprintf(输出)、格式化字符串函数sscanf(读取输入)、解析一个字符串、
字符串查找字符函数strchr、字符串查找子串函数strstr、字符串分割函数strtok、
atoi函数、atof函数、atol函数、解析一个字符串的高级应用。
2、函数的定义和声明、函数的形式参数(形参)与实际参数(实参)、函数的返回值类型和返回值、
return函数与exit函数(exit更猛,不受位置限制)、自定义一个函数,实现大小写字母的互相转换功能、
自定义一个函数,实现atoi的功能。
3、函数的递归、递归例子:有n个人排成一队、递归例子:将10进制数转化为二进制数、
递归例子:将10进制数转化为16进制、递归例子:菲波那切数列、递归的优点与缺点。
4、多个源代码文件程序如何编译、头文件的使用、解决预编译时会出现多次函数声明问题。
“我是一名从事了10年开发的老程序员,最近我花了一些时间整理关于C语言、C++,自己有做的材料的整合,一个完整的学习C语言、C++的路线,学习材料和工具。C/C++、编程爱好者的聚集地就在我这里 企鹅进<C语言C++编程学习>!欢迎初学和进阶中的小伙伴。希望你也能凭自己的努力,成为下一个优秀的程序员。工作需要、感兴趣、为了入行、转行需要学习C/C++的伙伴可以跟我一起学习!”
=============================================================================
C语言库函数
1、字符串处理函数:字符输入函数和字符输出函数
字符输入函数:gets和fgets
通过scanf输入的时候,最后按的是一个什么键?答:回车键,scanf会把回车键认为是输入完成,而不是字符串的内容。
而且scanf认为回车和空格都代表输入完成哦。
当字符数组的成员数量小于用户在键盘输入字符的数量之后,scanf并不会自动处理,而是把用户输入的所有字符都放入了数组,导致了数组溢出了,内存出错,程序崩溃。
-----------------------------------------------------------------------------
gets认为只有回车代表输入完成,空格只是字符串中的一部分而已。
gets和scanf一样有缓冲区溢出的危险。
-----------------------------------------------------------------------------
字符数组 的英文名字是 char []
gets()函数的基本用法为:
char *gets(char *s);
该函数的参数是一个字符数组,该函数的返回值也是一个字符数组。
linux下示例代码如下:
1 #include
2
3 int main()
4 {
5 char a[100] = { 0 };
6 gets(a);
7 printf("%s\n", a);
8 return 0;
9 }
-----------------------------------------------------------------------------
编译时会出现一个warning,建议我们不要使用gets函数了。我们暂时不管他,先直接运行看结果。
--------------------------------------
警告如下:
a2.c:6:5: warning: implicit declaration of function ‘gets’ [-Wimplicit-function-declaration]
gets(a);
^
/tmp/cceyMQ7u.o: In function `main':
a2.c:(.text+0x41): warning: the `gets' function is dangerous and should not be used.
--------------------------------------
原因:
问题出在程序中使用了 gets是非常不安全的。这是对程序产生BUG,出现不可靠性的一个描述,
有些函数在某些意外情况会导致程序陷入不可控状态,仅仅是PC上运行最多也就是退出而已,
但是如果是运行在飞机等系统里的话,就会有大麻烦,说危险也不为过。因为英文文献里描述为dangerous,所以也就翻译为危险。
函数执行需要一个栈空间,但这个栈空间容量是有限的,而且栈里存放了函数返回的地址。
gets()函数在获取输入时,如果无限输入会造成栈空间溢出,在程序返回时,不能正常的找到返回地址,程序将发生不可预测行为。
--------------------------------------
解决:
解决办法是使用 fgets,但由于fgets函数是为读取文件设计的,所以读取键盘是没有gets那么方便。
fgets(char *s, int size, FILE *stream);
第一个参数是:字符类型的数组,第二个参数是:标明这个数组的大小,第三个参数是:如果总是通过键盘输入的话,可以固定写为stdin。
fgets()函数的基本用法为:
-------------------------------------
示例程序:
/*代码实现01_使用fputs函数打印输出*/
#include <stdio.h>
int main ( )
{
char name[20] = { 0 };
fgets(name, sizeof(name), stdin);//stdin 意思是键盘输入
fputs(name, stdout); //stdout 意思是通过打印设备输出
return 0;
}
--------------------------------------
/*代码实现02_使用printf函数打印输出*/
#include
int main ( )
{
char name[20] = { 0 };
fgets(name, sizeof(name), stdin);//stdin 意思是键盘输入
printf("%s", name);//这边输出不需要 \n 了,实际操作时,fgets会认为用户输入的回车也是字符串的一部分内容。即输出的内容中间接地带了 \n 了。
return 0;
}
-----------------------------------------------------------------------------
fgets会认为用户输入的回车也是字符串的一部分内容。
fgets是安全的,不会因为用户恶意的输入过长的字符串导致溢出。因为它只接受它能存的最大的字符数,其余的舍掉!
=============================================================================
字符输出函数:puts和fputs
puts函数打印字符串时,与printf不同,puts会在最后自动增加一个换行字符 '\n'。
puts不支持各种转义字符,如%d,%s都不支持,puts只能简单直接地输出一个字符串,而不能输出char类型(字符类型)、int类型(整型)、double类型(双精度浮点类型)等其他类型。
linux下示例代码如下:
1 #include
2
3 int main()
4 {
5 char a[] = "hello world";
6 puts(a);
7 return 0;
8 }
--------------------------------------
puts函数内部可能是如下这样实现的:
int puts(const char *s)
{
int index = 0;
while(s[index])
{
putchar(s[index]);
index++;
}
putchar('\n');
return index;
}
putchar函数的作用:向终端输出一个字符。
(1)putchar函数只能用于单个字符的输出,且一次只能输出一个字符。
(2)在程序中使用putchar函数,务必牢记:在程序(或文件)的开头加上编译预处理命令(也称包含命令),即:#include "stdio.h"。
//思考
用putchar就可以实现puts,printf等输出函数。
用getchar就可以实现scanf,gets等输入函数。
-----------------------------------------------------------------------------
fputs函数是puts函数的文件操作版本。
int fputs(const char *s, FILE *stream); //注意:const用来修饰char *s, *s的内容不可变。
第一个参数是一个char的数组;第二个参数是:如果总是通过屏幕进行输出的话,可以固定写为stdout。
fputs并不会像puts那样输出的时候自动结尾加 \n 。
linux下示例代码如下:
1 #include
2
3 int main()
4 {
5 char a[] = "hello world";
6 //puts(a); //hello world
//root@iZ2zeeailqvwws5dcuivdbZ:~/1/01#
7 //printf(a); //hello worldroot@iZ2zeeailqvwws5dcuivdbZ:~/1/01# 编译有警告哦
8 fputs(a, stdout); //hello worldroot@iZ2zeeailqvwws5dcuivdbZ:~/1/01#
9 return 0;
10 }
--------------------------------------
1 #include
2
3 int main()
4 {
5 char a[] = "hello world\n";
6 //puts(a);
7 //printf(a);
8 fputs(a, stdout); //hello world
9 return 0; //root@iZ2zeeailqvwws5dcuivdbZ:~/1/01#
10 }
=============================================================================
求字符串长度函数strlen
使用这个库函数时需要包含头文件<string.h>
"abc",注意:用strlen时返回的结果是3,而不是4。
strlen函数的基本用法为:
size_t strlen(const char *s);
参数是:一个字符数组。
返回值是:不包含字符串结尾'\0'的字符串的长度(注意:是字符串字节的总数哦!不同的系统下是不同的)。
linux下示例代码如下:
1 #include
2 #include
3
4 int main()
5 {
6 char a[] = "hello";//char a[] = "hello传智";
7 unsigned int index = 0;
8 /*
9 while (a[index])
10 {
11 index++;
12 }
13 */
14 index = strlen(a);
15 printf("%u\n",index);//5 //11
16 return 0;
17 }
=============================================================================
字符串追加函数strcat
strcat函数的基本用法为:
char *strcat(char *dest, const char *src);
参数是:第一个参数是一个字符数组,第二个参数是静态的字符数组。
返回值是:一个字符数组。
用strcat的时候要注意,第一个字符串一定要有足够的空间容纳第二个字符串。
linux下示例代码如下:
1 #include
2 #include
3
4 int main()
5 {
6 char a[100] = "abc"; //a不是空串时
7 char b[100] = "hello";
8 strcat(a,b); //将a和b合并为一个字符串,合并的结果放入a。
9 printf("%s\n", a); //abchello
10 return 0;
11 }
-----