zoukankan      html  css  js  c++  java
  • 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
    
  • 相关阅读:
    【洛谷 P4166】 [SCOI2007]最大土地面积(凸包,旋转卡壳)
    专题
    【洛谷 P3299】 [SDOI2013]保护出题人 (凸包,三分,斜率优化)
    【洛谷 P3628】 [APIO2010]特别行动队 (斜率优化)
    $POJ1995$ $Raising$ $Modulo$ $Numbers$
    快速运算模板(未完待续)
    $Luogu$ $P1879$ $[USACO06NOV]$ 玉米田 $Corn Fields$
    [转载] $AT2444$ 题解
    [转载] $CF117B$ 题解
    [转载] $CF543B$ 题解
  • 原文地址:https://www.cnblogs.com/shenlinken/p/8046341.html
Copyright © 2011-2022 走看看