【问题标题】:Copy string to pointer to pointer将字符串复制到指向指针的指针
【发布时间】:2010-09-27 15:27:25
【问题描述】:

我正在使用这个例子:

char *myData[][2] =
{{"John", "j@usa.net"},
 {"Erik", "erik@usa.net"},
 {"Peter","peter@algonet.se"},
 {"Rikard","rikard@algonet.se"},
 {"Anders","anders@algonet.se"}};   

char **tableData[6];
tableData[0] = myData[0];
tableData[1] = myData[1];
tableData[2] = myData[2];
tableData[3] = myData[3];
tableData[4] = myData[4];
tableData[5] = NULL;//null terminated array

而是想为姓名和电子邮件放置我自己的字符串。 (尝试将字符串 xyz 放入 myData,然后放入 tableData) 带有 myData 的 strcpy 不起作用。我已经尝试了指针和引用的所有组合,但它似乎没有复制字符串。有什么建议吗?

             ok--> strncpy(xyz, argv[i], strlen(argv[i]));
             ok--> strcpy(xyz + strlen(argv[i]), "\0");
run time stops here--> strncpy(myData[i][0], xyz, strlen(xyz));  
                   tableData[i] = myData[i];

【问题讨论】:

  • 这不是问题,但您应该更仔细地查看 strlen() 和 strncpy() 的作用。两行:ok--> strncpy(xyz, argv[i], strlen(argv[i]));好的--> strcpy(xyz + strlen(argv[i]), "\0");并不比 strcpy(xyz, argv[i]); 更安全(效率也低得多);

标签: arrays string char


【解决方案1】:

myData[][] 中的指针初始化后指向文字字符串。无法写入该内存。

您可以为新字符串分配新内存并将指向新字符串的指针放入myData。或者对于您似乎正在做的事情,只需存储指向 argv[] 字符串的指针(只要您以后不打算修改字符串)。

另外,请确保您要复制字符串的内存块足够大以容纳新字符串。

Software Monkey Edit:包括 \0 终止符;并确保在适当的时候释放内存。

【讨论】:

    【解决方案2】:

    创建您自己的数据本地副本并更改列表中的指针:

    char **newentry = malloc(sizeof(char*) * 2);
    newentry[0] = strdup(myNewName);
    newentry[1] = strdup(myNewEmail);
    tableData[i] = newentry;
    

    这是最简单的部分。完成后最困难的部分是释放内存。如果这只是一个一次性的 C 程序,您可能可以在不释放内存的情况下逃脱,因为操作系统会在应用退出时自动释放它。

    但如果你想用大写的“P”正确地做到这一点,我会做几个小功能来复制和释放表格项目:

    void tableFreeItem(int i)
    {
        if(tableData[i] != 0)
        {
           free(tableData[i][0]);
           free(tableData[i][1]);
           free(tableData[i]);
        }
    }
    
    void tableSetItem(int i, char *name, char *email)
    {
        tableFreeItem(i);
    
        tableData[i] = malloc(sizeof(char *) * 2);
        tableData[i][0] = strdup(name);
        tableData[i][1] = strdup(email);
    }
    

    现在我们可以随意替换列表中的项目,并且可以通过调用 tableFreeItem() 函数轻松释放内存。以下是如何使用这些函数的示例:

    #define TABLE_SIZE 5
    
    char **tableData[TABLE_SIZE + 1]; /* +1 to make room for NULL terminator */
    
    /* Clear out the table. This also sets up the NULL terminator at the end. */
        memset(tableData, 0, sizeof(tableData));
    
    /* Copy the original data into the table */
        for(i = 0; i < TABLE_SIZE; i++)
            tableSetItem(i, mydata[i][0], myData[i][1]);
    
    /* Change a data item */
        tableSetItem(3, "Adam Pierce", "adam@doctort.org");
    
    /* Free memory when we have finished */
        for(i = 0; i < TABLE_SIZE; i++)
            tableFreeItem(i);
    

    免责声明:我没有尝试编译或运行此代码,我只是从头顶撞了它。它可能会起作用。

    【讨论】:

      猜你喜欢
      • 2015-01-17
      • 1970-01-01
      • 1970-01-01
      • 2013-04-26
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2011-11-01
      相关资源
      最近更新 更多