【问题标题】:strncpy and strcat garbage characters in CC中的strncpy和strcat垃圾字符
【发布时间】:2016-03-03 12:38:05
【问题描述】:

我尝试编写一个程序,它从字符串 s1 复制第一个 k 字符,然后将结果与从位置 i 开始的字符串 s2 的其余部分连接起来 然后在结果中连接 s1 的其余部分。然而我对strncpy 有一些问题。 它在控制台中显示了一些奇怪的字符,例如@。

这是我的代码:

char* strninsert(char *s1, char *s2, int k,int i)
{
    int n=strlen(s1)+strlen(s2)+10; // if i put for exemple 1000 it works
    char *result=(char*)malloc(n*sizeof(char));
    result[0]='\0';
    strncpy(result,s1,k);
    strcat(result,(s2+i));
    strcat(result,(s1+k));
    puts(result);
    return(result);
}

int main()
{
    int lens;
    printf("size string 1 ");
    scanf("%d",&lens);
    char *s=(char*)malloc((lens+1)*sizeof(char));
    getchar();
    fgets(s,lens+1,stdin);

    int lenx;
    printf("enter size string 2 ");
    getchar();
    scanf("%d",&lenx);
    char *x=(char*)malloc((lenx+1)*sizeof(char));
    getchar();
    fgets(x,lenx+1,stdin);

    int lentemp=lenx+lens;
    char *temp=(char*)malloc((lentemp+1)*sizeof(char));

    temp=strninsert(s,x,2,3);
    puts(temp);
    return(0);
}

它在 strncpy 指令之后向我显示了奇怪的字符,例如 poes@<line.

【问题讨论】:

  • strncpy man page says: "警告:如果 src 的前 n 个字节中没有空字节,则放在 dest 中的字符串不会以空值结尾"。也就是说,如果您的代码中的值k 小于strlen(s1)+1,那么result 中的结果内容将不会被NUL 终止。
  • 这段代码存在很多问题,比如内存泄漏、malloc 的结果转换(这是一种病)、格式错误。 ki 变量的用途是什么?因为它们是造成此问题的主要原因。
  • 停止使用strncpy。请改用snprintf
  • char s[lens+1]; 比所有 malloc 乱码都简单
  • @kaylum 非常感谢你,所以我必须在指令 strncpy 之后添加 result[k]='\0' ?它应该可以正常工作

标签: c string strcpy strcat strncpy


【解决方案1】:

正如 kaylum 之前回答的那样,strncpy 的结果不一定是字符串。这在将其传递给 strcat 时会造成危险,因为 strcat 要求两个参数都必须是字符串。

我能想到的解决问题的最佳方法是使用sprintf,如下所示:

void solution(char *destination, char *x, int x_size, char *y) {
    sprintf(destination, "%*.s%s", x_size, x, y);
}

【讨论】:

    【解决方案2】:

    strncpy man page says:

    警告:如果 src 的前 n 个字节中没有空字节,则 放在 dest 中的字符串不会以 null 结尾。

    也就是说,如果您的代码中的值k 小于strlen(s1)+1,那么result 中的结果内容将不会被NUL 终止。一种可能的解决方法是更改​​您的代码:

    /* Sanity check. */
    if (k > strlen(s1)) {
        k = strlen(s1);
    }
    
    strncpy(result , s1, k);
    result[k] = '\0';
    

    此外,与您的问题没有直接关系,但您的代码中存在内存泄漏。

    1. temp 变量主要接收到 malloc 缓冲区,然后由于 tempstrninsert 结果覆盖而立即丢失。
    2. strninsert 的结果是不会在任何地方释放的动态内存。

    【讨论】:

    • 非常感谢您抽出宝贵时间,这对我非常有用,一切正常。非常感谢
    猜你喜欢
    • 2016-03-14
    • 2021-11-05
    • 2020-04-19
    • 2015-08-16
    • 2016-02-10
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2015-01-28
    相关资源
    最近更新 更多