文章目录
- sprintf & snprintf 函数使用
- 使用 sprintf 的常见问题
- strncpy, strncat和snprintf的区别
sprintf & snprintf 函数使用
sprintf 函数使用
在将各种类型的数据构造成字符串时,sprintf 的强大功能很少会让你失望。
由于 sprintf 跟 printf 在用法上几乎一样,只是打印的目的地不同而已,
前者打印到字符串中,后者则直接在命令行上输出。这也导致 sprintf 比 printf 有用得多
sprintf()函数用于将格式化的数据写入字符串,其原型为:
int sprintf(char *str, char * format [, argument, …]);
【参数】str为要写入的字符串;format为格式化字符串,与printf()函数相同;argument为变量。
1.sprintf,不安全,参数不带缓冲区长度, 成功返回字符串长度, 格式化的字符串带结束符, 编译器都支持。 越界了程序不会立刻崩溃,难以发现。
2.snprintf, 安全,参数带缓冲区长度,成功返回字符串长度, 格式化的字符串带结束符, 缓冲区不足时截断字符串,同时返回格式化字符串需要的buffer长度(不包括结束符)。
使用 sprintf 的常见问题
sprintf是个变参函数,使用时经常出问题,而且只要出问题通常就是能导致程序崩溃的内存访问错误,但好在由sprintf误用导致的问题虽然严重,却很容易找出,无非就是那么几种情况,通常用眼睛再把出错的代码多看几眼就看出来了。
- 缓冲区溢出
第一个参数的长度太短了,没的说,给个大点的地方吧。当然也可能是后面的参数的问题,建议变参对应一定要细心,而打印字符串时,尽量使用“%.ns”的形式指定最大字符数。 - 忘记了第一个参数
低级得不能再低级问题,用 printf 用得太惯了。 - 变参对应出问题
通常是忘记了提供对应某个格式符的变参,导致以后的参数统统错位,检查检查吧。尤其是对应“*”的那些参数,都提供了吗?不要把一个整数对应一个“%s”,编译器会觉得你欺她太甚了。 - 安全性
strncpy, strncat和snprintf的区别
不保证内容正确.
- char *strncpy(char *dest, const char *src, size_t n);
最多从src中拷贝n个字符到dest。如果src的大小小于n,那么dest剩下的部分将被填0;
如果src的大小大于等于n,那么dest剩下的部分不会被填0,于是dest将不会以0结束。
char *strncat(char *dest, const char *src, size_t n);
最多从源中拷贝n个字符到目标串中,并在后面加一个0;也就是说,最多会有n+1个字符被写进dest。如果dest的容量为n,那么将会dest将会溢出。
int snprintf(char *str, size_t size, const char *format, …);
最多从源串中拷贝size-1个字符到目标串中,然后再在后面加一个0。所以如果目标串的大小为size的话,将不会溢出。
所以,字符串拷贝,最好用snprintf。
memcpy的操作对象是无格式的二进制数据,操作结束的判断取决于给定的参数。
strncpy的操作对象是ASCIIZ字符串,也就是说他的操作结束判断多一个条件(是否遇到’/0’);