c语言snprintf函数的用法详解
作者:为搬砖记录
snprintf()函数是一种格式化函数,用于将格式化的字符串存储到一个字符数组中,并且有一个参数用来限制输出的最大字符数。
语法:
int snprintf ( char * s, size_t n, const char * format, … );
参数:
- s:指向要存储字符串(由format参数格式化)的字符数组。
- n:指定存储字符串的最大字符数(不包括NULL结尾)。
- format:是格式字符串,用于格式化输出字符串。
返回值:
- 该函数返回实际写入的字符数(不包括NULL结尾)。
snprintf()函数的最大特点是它可以防止由于格式化字符串太长而导致的缓冲区溢出,它可以自动截断字符串,以确保不会超出缓冲区限制。
实例:
例如,下面的示例使用snprintf()函数将字符串“Hello world”存储到一个大小为10个字符的字符数组中:
#include <stdio.h> int main( ) { char str[10]; snprintf(str, 10, "Hello world"); printf("%s\n", str); return 0; }
输出:
Hello wor
这里面包含一个’\0’
特别注意
1. 无论何时一定会在字符串末尾添加'\0' 字符串结束符。
- 当字符串长度小于size时,会直接在字符串的末尾添加'\0';
- 当字符串长度等于size时,会取前size-1个字符,并在末尾添加‘\0’(即:加上'\0'后,一共size个字符);
- 当字符串长度大于size时,只取前size-1个字符,并在末尾添加'\0'(即:加上'\0'一共size个字符);
综上:snprintf不仅一定会自动在字符串末尾添加'\0',而且一定会尊重指定长度size的大小,不会超过该长度(算上自动在末尾增加的'\0')。所以从这一点来讲,使用snprintf是相对比较安全的,不用担心会出现overflow的情况。
NOTE:这一点上,snprintf与strncpy是有区别的。strncpy虽然也会指定目的内存的大小,但是当源字符串长度大于指定的内存大小时,strncpy虽然在达到指定大小后会停止copy,但是并不会在末尾自动添加'\0'。这样,在访问字符串时,有可能出现overflow的情况,因为末尾没有字符串结束符'\0'。
思考:
(1)当目的内存实际长度为N1,但是在使用snprintf时指定的实际size(第二个参数)为N2, 且N2<N1,可能会出现什么情况?
(2)如果N2>N1,又可能出现什么情况?
2. 特别小心返回值。
- 当出现错误时,会返回负值;
- 当字符串长度小于size时,返回打印到目的内存的实际字符串长度(不包括'\0');
- 当字符串长度大于等于size时,尽管字符串会被截断(只有size-1个字符串被打印到目的内存),但是返回值却会返回源字符串的实际长度(即假设目的内存无限大,总是能写下源字符串)。
综上:snprintf的返回值可能大于或等于指定的size,这时候说明目的内存不够大,源字符串被截断,需要小心处理,这是否是期望发生的情形。
NOTE:有一些写法会利用snprintf的这个特点来确定合适的目的内存大小,例如:
const char *fmt = "sqrt(2) = %f"; char * buf; int sz = snprintf(NULL, 0, fmt, sqrt(2)); buf = (char *)malloc(sz+1); // +1 for append '\0' snprintf(buf, sz+1, fmt, sqrt(2));
总结
到此这篇关于c语言snprintf函数用法的文章就介绍到这了,更多相关c语言snprintf函数用法内容请搜索脚本之家以前的文章或继续浏览下面的相关文章希望大家以后多多支持脚本之家!