• snprintf 返回值陷阱 重新封装


    snprintf()函数用于将格式化的数据写入字符串,其原型为:

        int snprintf(char *str, int n, char * format [, argument, ...]);
    
    • str为要写入的目标字符串;
    • n为能写入的字符的最大数目,超过n会被截断,包括''符,所以能最大写入的其实是n-1个字符;
    • format为格式化字符串,使用方式与printf()函数相同;
    • argument为变量,可为多个,取决于format,这里的使用方式与printf相同。
    • 成功则返回参数str 字符串长度(不包括“”),失败则返回-1,错误原因存于errno 中。

    snprintf()可以认为是sprintf()的升级版,比sprintf()多了一个参数,可以控制要写入的字符串的长度,更加安全,不会造成str的溢出。

    不过snprintf也不是尽善尽美的,也有陷阱,当要写入的argument的长度大于str的长度时,返回值不是str的长度,而是argument的长度

    #include <stdio.h>
    #include <stdlib.h>
    
    int main(void)
    {
    	int len;
    	char str[5];
    	len = snprintf(str, sizeof(str), "%s", "ABCDEFGH");
    	printf("str:%s, len:%d.
    ", str, len);
    
    	return 0;
    }
    

    输出结果:

    str:ABCD, len:8.
    

    返回的长度是8而不是4,不注意的话,下边的使用可能有问题。所以,使用后,下边最好再判断一下len的长度是否超过了size。
    其实可以自己封装一个my_snprintf的

    #include <stdio.h>
    #include <stdlib.h>
    #include <stdarg.h>
    
    int my_snprintf(char *dst, int size, char *fmt, ...)
    {
    	int len;
    	va_list argp;
    	va_start(argp, fmt);
    	len = vsnprintf(dst, size, fmt, argp);
    	len = len > size - 1 ? size - 1 : len;
    	va_end(argp);
    	
    	return len;
    }
    
    int main(void)
    {
    	char str[8];
    	int len;
    	
    	len = my_snprintf(str, sizeof(str), "A:%d:%s", 1, "ABCDEFGH");
    	printf("str:%s, len:%d
    ", str, len);
    
    	return 0;
    }
    

    输出:

    str:A:1:ABC, len:7
    
  • 相关阅读:
    eclipse/myeclipse介绍
    HDU 5802 Windows 10
    LaTeX test
    数据结构2 静态区间第K大/第K小
    数据结构1 「在线段树中查询一个区间的复杂度为 $O(log N)$」的证明
    HDU 1007 Quoit Design
    HDU 5761 Rower Bo
    hihocoder #1341 Constraint Checker
    HDU #5733 tetrahedron
    hihocoder #1327
  • 原文地址:https://www.cnblogs.com/shenlinken/p/8046341.html
Copyright © 2020-2023  润新知