C:使用sprintf和strncpy将数据插入到指针数组中

时间:2009-03-31 06:24:21

标签: c printf strncpy

我的结构有一个指针数组。我想以字符串格式插入数组数字,即“1”,“2”等。

但是,使用sprintf或strncpy有什么不同吗?

我的代码有什么重大错误吗?我知道我必须免费打电话,我会在我的代码的另一部分中这样做。

非常感谢任何建议!

struct port_t
{
    char *collect_digits[100];

}ports[20];

/** store all the string digits in the array for the port number specified */
static void g_store_digit(char *digit, unsigned int port)
{
    static int marker = 0;
    /* allocate memory */
    ports[port].collect_digits[marker] = (char*) malloc(sizeof(digit)); /* sizeof includes 0 terminator */
    // sprintf(ports[port].collect_digits[marker++], "%s", digit);
    strncpy(ports[port].collect_digits[marker++], digit, sizeof(ports[port].collect_digits[marker]));
}

5 个答案:

答案 0 :(得分:3)

是的,您的代码存在一些问题。

  • 在C中,不要转换malloc()的返回值。它不是必需的,可以隐藏错误。
  • 您根据指针的大小分配空间,而不是您要存储的大小。
  • 复制相同。
  • 目前还不清楚静态marker的作用,以及它周围的逻辑是否正确。 port是要更改的插槽,还是由静态变量控制?

您是想在数组中每个插槽只存储一位数,还是多位数?

根据声明,以下是该功能的外观:

/* Initialize the given port position to hold the given number, as a decimal string. */
static void g_store_digit(struct port_t *ports, unsigned int port, unsigned int number)
{
  char tmp[32];

  snprintf(tmp, sizeof tmp, "%u", number);
  ports[port].collect_digits = strdup(tmp);
}

答案 1 :(得分:2)

strncpy(ports[port].collect_digits[marker++], digit, sizeof(ports[port].collect_digits[marker]));

这是不正确的。

你已经在collect_digits上分配了一定数量的内存。

将char *数字复制到该内存中。

您应该复制的长度是strlen(数字)。您实际复制的是sizeof(ports [port] .collect_digits [marker]),它将为您提供单个char *的长度。

您不能使用sizeof()来查找已分配内存的长度。此外,除非您事先知道数字与您分配的内存长度相同,即使sizeof()确实告诉您已分配内存的长度,您也会复制错误的字节数(太多;只有你自己)需要复制数字长度。)

另外,即使两个长度总是相同的,获得长度的方式也不具有表现力;它误导了读者。

另请注意,如果指定的副本长度大于源字符串的长度,strncpy()将使用尾随NULL填充。因此,如果数字 分配的内存长度,您将拥有一个非终止字符串。

sprintf()行在功能上是正确的,但对于你正在做的事情,strcpy()(而不是strncpy())是从我能看到和知道的代码,正确的选择。

我不得不说,我不知道你要做什么,但代码感觉非常尴尬。

答案 2 :(得分:1)

第一件事:为什么有一个指针数组?您期望端口对象有多个字符串吗?您可能只需要一个普通数组或一个指针(因为您稍后会malloc)。

struct port_t
{
    char *collect_digits;
}ports[20];

您需要传递字符串的地址,否则,malloc会对本地副本执行操作,您永远不会收回您所支付的内容。

static void g_store_digit(char **digit, unsigned int port);

最后,sizeof适用于指针上下文,但没有给出正确的大小。

答案 3 :(得分:1)

不使用malloc()strncpy(),而是使用strdup() - 它会分配足够的缓冲区以保存内容并将内容复制到新字符串中,一次性完成。

因此您根本不需要g_store_digit() - 只需使用strdup(),并在调用方级别维护marker

答案 4 :(得分:1)

原始代码的另一个问题:声明

strncpy(ports[port].collect_digits[marker++], digit, sizeof(ports[port].collect_digits[marker]));

在同一表达式中引用markermarker++。在这种情况下,++的评估顺序为undefined - 可以在执行增量之前或之后评估对marker的第二次引用。