【问题标题】:I need some clarification about sprintf() and array[]我需要澄清一下 sprintf() 和 array[]
【发布时间】:2020-08-13 05:11:32
【问题描述】:
char buff[10]={0};
char buff1[6]="xxxxx";
sprintf(buff,"My name is %s");

这是 buff(即 10)的正确数组初始化吗?或者我需要用 17 进行初始化。

【问题讨论】:

  • 初始化没问题,但是对sprintf()的调用是致命的——你没有提供一个由%s格式化的值,所以你有未定义的行为,任何事情都可能发生。 buff 的数组大小可能太小,但代码与此分开。
  • 您绝对应该turn up your compiler's warning level,直到它为您提供有关sprintf 电话的信息。不匹配的格式字符串不应该在这个时代得到解决,但编译器比这更进一步。
  • AADHI A.R,最好选择一种语言:这里是 C 或 C++。

标签: c linux printf


【解决方案1】:

如果您要用sprintf 覆盖它,那么它不需要包含任何特别的东西,它只需要足够大以容纳数据

换句话说,= {0} 就足够了,在这种情况下实际上是可选的。

PSA:请勿使用函数,如 sprintf,缺少长度参数。而是使用 snprintf 和有长度参数的相关函数。如果不采取适当的预防措施,缓冲区溢出错误是 C 语言中的一个大问题。

你应该拥有的 C 代码大致如下:

size_t buff_size = 255;
char buff[buff_size];
char* name = "Aadhi";

snprintf(buff, buff_size, "My names is %s", name);

其中不仅包含占位符参数,而且重要的是,应该使用的值。

在 C++ 中,你应该完全跳过这个,而是:

std::string name = "Aadhi";
std::string message = "My name is " + name;

std::string 避免了几乎所有与缓冲区溢出错误有关的问题。

C++ 20 引入了一个新的std::format 功能,它的工作原理与sprint 非常相似,但没有所有缓冲区溢出问题:

std::string name = "Aadhi";
std::string message = std::format("My name is {}", name);

【讨论】:

  • 请注意,修改后的数组 (char buff[buff_size];) 在 C 中是 VLA(可变长度数组),在 C++ 中是非法的(尽管g++ 允许这样做)。
  • @JonathanLeffler 我添加了一个 C++ 示例来区分。
  • 虽然没有缓冲区溢出,但没有检查snprintf()的返回值,代码已经避免了一个问题,但仍然存在另一个问题:缓冲区太小无法区分大小正好的缓冲区。一个错误,虽然更容易驯服,但仍然存在。
猜你喜欢
  • 2017-01-18
  • 2021-07-11
  • 1970-01-01
  • 1970-01-01
  • 2021-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多