【问题标题】:Snprintf not working in CSnprintf 在 C 中不工作
【发布时间】:2017-04-28 15:49:46
【问题描述】:

谁能帮我解决我的错误...

接下来会发生什么:

我的程序被称为“打开”

这是我的输出:

user@host:~$ ./open open A
A
open
Error: Cannot creat ./././.: Is a directory
./././.user@host:~$

为什么输出结果是././././ 而不是./A/open

我知道问题来自av[2]

printf("%s\n", av[2]);
printf("%s\n", av[1]);
snprintf(av[2], sizeof(av[2]), "./%s/%s", av[2], av[1]);
printf("%s", av[2]);

【问题讨论】:

  • sizeof(av[2])是指针的大小,大概是4字节。
  • 所以我必须将其更改为其他内容?我尝试删除它,但结果是分段错误。
  • 为什么要将结果存储到av[2]?除了已经包含的内容之外,它可能没有空间容纳任何额外的字符。
  • 请显示更多代码。 av 是什么?阅读:minimal reproducible example:
  • 程序参数的通常名称是argv[]。使用你自己的名字会使问题变得混乱。

标签: c linux printf


【解决方案1】:

snprintf(av[2], sizeof(av[2]), "./%s/%s", av[2], av[1]);由于各种原因无效。

  1. 使用snprinf(),其中源和目标重叠是UB。

  2. sizeof(av[2]) 是指针的大小,在本例中为 8,而不是数组的大小。

  3. 很可能av[2] 的大小不足以保存串联。

【讨论】:

  • 我现在得到了 size 部分,但是 snprinf 和 sprintf 有什么区别?
  • @mmm snprintf() 要求您提供目标字符串的大小,以免溢出。
  • @mmm 使用snprintf() 是防止出现过多打印字符串问题的两个步骤之一。第二步是使用int len = snprintf(...., size, ....)的返回值-->if (len < 0 || len >= size) Handle_Problem()。如果没有第二步,后续代码可能会使用意外的字符串。考虑snprintf(buf, 13, "%s", "Launch missles not");
【解决方案2】:

第一个问题是av[2]是一个指针,所以sizeof(av[2])是一个指针的大小,而不是数组中的字符数。

第二个问题是如果这是程序的argv[] 数组,每个元素只有实际参数的空间——你不应该尝试在其中存储更长的字符串。

解决方案是分配一个足够大的新字符串来满足您的需求

size_t newlen = strlen(av[1]) + strlen(av[2]) + 4; // + 3 for ./ and /, +1 for trailing null
char *path = malloc(newlen);
if (!path) {
    printf("Unable to allocate\n");
    exit(1);
}
sprintf(path, "./%s/%s", av[2], av[1]);
printf("%s", path);

在这种情况下,没有必要使用snprintf(),因为我们计算出path 的大小足以进行连接。

【讨论】:

  • 是的,它是 argv[] 数组。谢谢你的解释。了解有关 C 的更多信息
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2019-10-25
  • 1970-01-01
  • 2017-08-09
  • 1970-01-01
相关资源
最近更新 更多