【问题标题】:C: using sprintf and strncpy inserting data into an array of pointersC:使用 sprintf 和 strncpy 将数据插入指针数组
【发布时间】:2009-03-31 06:24:21
【问题描述】:

我有一个包含指针数组的结构。我想以字符串格式插入数组数字,即“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]));
}

【问题讨论】:

    标签: c printf strncpy


    【解决方案1】:

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

    • 在 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);
    }
    

    【讨论】:

      【解决方案2】:
      strncpy(ports[port].collect_digits[marker++], digit, sizeof(ports[port].collect_digits[marker]));
      

      这是不正确的。

      您已为 collect_digits 分配了一定数量的内存。

      您将 char *digits 复制到该内存中。

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

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

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

      还要注意,如果指定的复制长度大于源字符串的长度,strncpy() 将用尾随 NULL 填充。因此,如果数字分配的内存长度,你将有一个非终止字符串。

      sprintf() 行在功能上是正确的,但就您所做的而言,strcpy()(与 strncpy() 相对)是,从我所看到和知道的代码来看,是正确的选择。

      不得不说,我不知道你想做什么,但是代码感觉很别扭。

      【讨论】:

        【解决方案3】:

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

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

        您需要传递字符串的地址,否则,malloc 将作用于本地副本,您将永远无法取回您支付的费用。

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

        最后,sizeof 应用在指针上下文中,并没有给你正确的大小。

        【讨论】:

        • sizeof 运算符当然不仅仅适用于数组。 { 诠释 x; printf("x 是 %d 个字符\n", sizeof x); } 完全有效,看不到数组。
        • @unwind:当然。我的意思是在这种情况下。
        【解决方案4】:

        不要使用malloc()strncpy(),只需使用strdup() - 它会分配足够的缓冲区来容纳内容并将内容复制到新字符串中,一键完成。

        所以您根本不需要g_store_digit() - 只需使用strdup(),并在调用者级别维护marker

        【讨论】:

          【解决方案5】:

          原代码的另一个问题:语句

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

          在同一表达式中引用 markermarker++。在这种情况下,++ 的求值顺序是undefined——第二个对marker 的引用可以在执行递增之前或之后求值。

          【讨论】:

            猜你喜欢
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            • 2012-08-29
            • 2021-02-19
            • 2016-12-05
            相关资源
            最近更新 更多