在使用snprintf函数中使用sizeof运算符是否安全?

5
在使用"snprintf"时,使用sizeof运算符是否可以?例如。
   char cstring[20];
   snprintf(cstring,sizeof(cstring),"%s","somestring......");

2
你已经使用了 c++ 标签标记了你的问题。实际上,在 C++ 中,如果有可能,我们不会使用 snprintf 而是使用 std::ostringstream。如果你只是对 C 解决方案感兴趣,请考虑删除 c++ 标签。 - 5gon12eder
1
你为什么认为这不好呢? - Ed Heal
@EdHeal,我觉得这很好,但是我想确认一下(有人在任何平台上遇到过任何问题吗)? - Rahul_cs12
@EdHeal 我也不确定,因为 cstring 没有被初始化。所以根据我几乎没有的 C++ 知识,sizeof(cstring) 可能是 020 或未定义的。 - Eric Duminil
@EricDuminil - 它的大小不取决于其内容。 - Ed Heal
@EdHeal 好的。但是例如 strlen 会,对吧? - Eric Duminil
5个回答

7

没问题,你提供的具体案例很好,除了你没有检查返回值,所以你不会知道字符串是否被截断。


2
@TimHarper:这取决于应用程序。在某些安全敏感的应用中,截断字符串可能会导致安全漏洞,因此不检查返回值甚至比分段错误更糟糕。 - John Zwinck
我不确定我理解了,您是说在某些安全敏感的应用程序中,有时允许OOB写入更好? - Tim Harper
2
@TimHarper:我想说的是,截断和越界写入都可能存在安全隐患,我们无法预先知道哪一个更好。两者都不好,它们都很糟糕。 - John Zwinck

5

你所发布的示例看起来不错。

但是,在任何数组退化为指针的情况下,这种写法都是不正确的:

void func(char s []) {
    snprintf(s,sizeof(s),"%s","somestring......"); // Not fine, s is actually pointer
}
int main(void) {
    char cstring[20];
    func(cstring); // Array decays to pointer

4

snprintf 中您可以使用 sizeof 操作符,但如果字符串的长度大于您指定的大小,则字符串中剩余的字符将丢失。


2

是的,你可以使用。但是如果字符串长度大于sizeof值,则该字符串将被截断,或者最多存储给定值在该数组中。


1
#include <stdio.h>                                                                                                                            
int main()                                                                                                                                    
{                                                                                                                                             
        char str[16];                                                                                                                         
        int len;                                                                                                                              

        len = snprintf(str, sizeof( str ), "%s %d %f", "hello world", 1000, 10.5);                                                            
        printf("%s\n", str);                                                                                                                  

        if (len >= 16)                                                                                                                        
        {                                                                                                                                     
                printf("length truncated (from %d)\n", len);                                                                                  
        }                                                                                                                                     
} 

output:
=======
 ./a.out
hello world 100
length truncated (from 26)

/* You can see from the output only 15 char + '\0' is displayed on the console ( stored in the str ) */


/* Now changing the size of the str from 16 to 46 */

#include <stdio.h>
int main()
{

        char str[46];
        int len;

        len = snprintf(str, sizeof( str ), "%s %d %f", "hello world", 1000, 10.5);
        printf("%s\n", str);

        if (len >= 46)
        {
                printf("length truncated (from %d)\n", len);
        }
}

output:
==========
./a.out
hello world 1000 10.500000

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接