学习记录:snprintf 和scnprintf的差别

在学习Linux sysfs文档时,注意到snprintf与scnprintf的使用区别。snprintf返回的是总长度,可能导致越界问题;而scnprintf在Linux内核中返回实际写入的长度,更安全。建议在处理用户态返回值时使用scnprintf。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

1,背景

      在学习Linux的过程中,偶然间看到了sys文件系统的说明文档:./Documentation/filesystems/sysfs.txt(系统版本为4.7.3),其中在说明文档中,有这么一段话:

- show() methods should return the number of bytes printed into the
  buffer. This is the return value of scnprintf(). 
- show() must not use snprintf() when formatting the value to be
  returned to user space. If you can guarantee that an overflow
  will never happen you can use sprintf() otherwise you must use
  scnprintf().
    但是,以前偶尔看到的Linux系统驱动源码中,却经常看到使用snprintf的情况,并且在某些博客甚至案例中点名了要使用这个函数,在Linux的官方文档中,却禁止使用这个函数的原因是什么?

2,snprintf和scnprintf 对比

首先看一下snprintf 

官方文档:http://www.cplusplus.com/reference/cstdio/snprintf/

The number of characters that would have been written if n had been sufficiently large, not counting the terminating null character.
If an encoding error occurs, a negative number is returned.
Notice that only when this returned value is non-negative and less than n, the string has been completely written.

运行一个demo查看一下:

#include <stdio.h>
#include <string.h>
int main (int argc, char *argv[])
{
    char buffer1 [10]= {""};
    int cx1;
    cx1 = snprintf (buffer1, 10, "%s", "justfor");

    printf("src lenth < n buffer1 is:%s, lenth is:%d return value:%d\n",buffer1, strlen(buffer1),cx1);

    char buffer2 [10]= {""};
    int cx2;
    cx2 = snprintf (buffer2, 10, "%s", "justfortes");

    printf("src lenth = n buffer2 is:%s, lenth is:%d return value:%d\n",buffer2, strlen(buffer2),cx2);
    
    char buffer3 [10]= {""};
    int cx3;
    cx3 = snprintf (buffer3, 10, "%s", "justfortest");

    printf("src lenth > n buffer3 is:%s, lenth is:%d return value:%d\n",buffer3, strlen(buffer3),cx3);
    return 0;
}


结果如下:



src lenth < n buffer1 is:justfor, lenth is:7 return value:7
src lenth = n buffer2 is:justforte, lenth is:9 return value:10//通过这个结果,可以看到其实buffer使用snprintf在n的位置是自动补\n的
src lenth > n buffer3 is:justforte, lenth is:9 return value:11//返回值过大,说明截断了


通过上面的返回值结果,我们能够看到,其实返回的数值是src的长度,而不是已经写入的长度,如果此时,再使用

buffer[xxlen]就有可能会出现越界的情况,比如上文中使用buffer[cx]就会越界;

关于 scnprintf

参考文章:https://www.kernel.org/doc/htmldocs/kernel-api/API-scnprintf.html

The return value is the number of characters written into buf not including the trailing '\0'. If size is == 0 the function returns 0.

因此,在linux kernel中作为返回用户态的一个value,建议使用scnpirnt



get



评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值