c库中的不安全函数

使用安全的函数可以最大限度减少代码中出现内存溢出的可能性

1 strncat代替strcat

不安全函数的定义为

1
char *strcat(char *dest, const char *src);

安全函数定义如下:

1
2
#include <string.h>
char *strncat(char *dest, const char *src, size_t n);

从src中最多追加n个字符到desc字符串的后面。
当src包含n个以上的字符时,desc的空间至少为strlen(dest)+n+1,因为该函数还会追加字符串结束符’\0’到dest后面,一定要预留’\0’空间。
返回一个指向最终desc的指针
其实在c++11中还提供了strncat_s安全函数,感兴趣可行查阅

2 使用strncpy代替strcpy

不安全函数定义

1
2
#include <string.h>
char *strcpy(char *dest, const char *src);

安全函数定义为

1
2
#include <string.h>
char *strncpy(char *dest, const char *src, size_t n);

从src中最多复制n个字符到dest字符串中,与strncat一样,需要在desc中预留’\0’结束符的空间;
也是返回一个指向最终desc的指针;

3 使用snprintf代替sprintf

不安全函数定义为

1
int sprintf(char *str, const char *format, ...);

安全函数定义为

1
2
#include <stdio.h>
int snprintf(char *str, size_t size, const char *format, ...);

snprintf比前面两个更为安全,在往str中写数据时,最多会写入n个字节,其中包括字符串结束符’\0’;
成功则返回预写入的字符串长度,出错则返回负值

4 使用fgets代替gets

不安全函数定义为

1
char *gets(char *s);

安全函数定义为

1
2
#include <stdio.h>
char *fgets(cahr *s, int size, FILE *stream);

gets函数从不检查缓冲区的大小,并且是从标准输入中读取数据,这将导致缓冲区溢出;在c++11中,gets函数被删除;
fgets函数最多会复制size-1个字节的数据到缓存s中,并且在最后追加结束字符’\0’;
fgets在成功时,返回指向缓冲区s的指针

5 printf fprintf sprintf区分

5.1 c语言中的输出流

(1)标准输入流:stdin
(2)标准输出流:stdout
(3) 标准错误输出流: stderr
三者类型都是文件指针FILE,对应了在linux文件系统中的文件描述符值依次是0,1,2;
关于文件描述符与文件指针的转换可自行百度资料;

5.2 各种printf的区别

关于sprintf与snprintf的区别上面已经说明,没有fnprintf这个函数哈。
三者的定义如下:

1
2
3
int printf(const char *format,...);
int fprintf(FILE *stream, const char *format, ...);
int sprintf(char *str, const char *format, ...);

(1)printf
printf是标准输出流的输出函数,发送格式化输出到标准输出stdout,用来向屏幕这样的标准输出设备输出。
如果成功,则返回写入的字符总数,否则返回一个负数;
printf是有缓冲的输出,立即输出需要加上换行符’\n’;
(2)fprintf
fprintf是向文件输出,绑定文件指针,发送格式化输出到流stream中;
如果成功,则返回写入的字符总数,否则返回一个负数;
与printf不同的是,fprintf没有缓冲,而printf实际相当于fprintf(stdout, “%s xxxxx\n”,a);
(3) sprintf
发送格式化输出到 str 所指向的字符串中;
如果成功,则返回写入的字符总数,不包括字符串追加在字符串末尾的空字符。如果失败,则返回一个负数