将const char *复制到char数组中(面对一个bug)

时间:2016-04-23 05:42:08

标签: c

我有以下方法

{{"gsga","baf"},{"ad","aasb","asdf","asdfsd"},{"ads","sd","sd"}}

如果方法static void setName(const char * str,char buf [16])

中buf长度限制为16,请告诉我上面编码的正确方法是什么

2 个答案:

答案 0 :(得分:0)

当传递数组作为参数时,数组衰减到数组的FIRST元素的指针。必须定义规则,让方法知道元素的数量。

您声明<object style="(width and height in pixels)" type="text/html" data="http://my-wpsite.com" typemustmatch="typemustmatch"> <param name="data" value="http://my-wpsite.com"> Object unavailable at this moment. </object> ,将其传递给char mbuf[16]setName()将无法获得setName(),但会获得char[]

所以,声明应该是

char*

接下来,static void setName(const char* str, char* buf) 只能存储15个字符,因为最后一个字符必须是&#39; null终结符&#39;,这是&#39; \ 0&#39;。否则,将发生以下情况:

  

//如果我在代码中使用buf,则会导致虚假字符,因为长度大于16。

也许这会帮助您理解:

char mbuf[16]

所以代码应该是

char str[] = "foobar"; // = {'f','o','o','b','a','r','\0'};

另外,我建议你不要重新发明轮子,为什么不使用static void setName(const char* str, char* buf) { int sz = MIN(strlen(str), 15); // not 16 for (int i = 0; i < sz; i++) buf[i] = str[i]; buf[sz] = '\0'; // assert that you're assigning 'null terminator' }

strncpy

答案 1 :(得分:0)

以下代码将分配给缓冲区的内存大小传递给setName函数 这样,setName函数可以确保它不会在分配的内存之外写入 在函数内部,可以使用for循环或strncpy。两者都将由size参数sz控制,并且两者都要求在复制的字符后放置一个空终止符。同样,sz将确保在分配给缓冲区的内存中写入空终止符。

#include <stdio.h>
#include <stdlib.h>
#include <string.h>

static void setName(const char *str, char *buf, int sz);

int main()
{
    const int a_sz = 16;
    char* string = "This bit is OK!! but any more than 15 characters are dropped";

    /* allocate memory for a buffer & test successful allocation*/
    char *mbuf = malloc(a_sz);
    if (mbuf == NULL) {
        printf("Out of memory!\n");
        return(1);
    }

    /* call function and pass size of buffer */
    setName(string, mbuf, a_sz);
    /* print resulting buffer contents */
    printf("%s\n", mbuf); // printed: This bit is OK!

    /* free the memory allocated to the buffer */
    free(mbuf);
    return(0);
}

static void setName(const char *str, char *buf, int sz)
{
    int i;

    /* size of string or max 15 */
    if (strlen(str) > sz - 1) {
        sz--;
    } else {
        sz = strlen(str);
    }

    /* copy a maximum of 15 characters into buffer (0 to 14) */
    for (i = 0; i < sz; i++) buf[i] = str[i];
    /* null terminate the string - won't be more than buf[15]) */
    buf[i] = '\0';
}

更改一个值const int a_sz可以复制不同数量的字符。函数中没有大小的“硬编码”,因此如果以后修改代码,可以降低出错的风险。

我用一个简单的if ... else结构替换了MIN,以便我可以测试代码。