【问题标题】:string.h functions - strncpy and strncat strange behaviourstring.h 函数 - strncpy 和 strncat 奇怪的行为
【发布时间】:2021-07-23 23:59:23
【问题描述】:

我正在测试一些string.h 函数,发现在使用函数strncpystrncat 时出现了奇怪的行为。

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

int main()
{
    char name1[30], name2[30], name3[30], name4[30], name5[30];
    char *res;
        
    printf("First name: ");
    scanf("%[^\n]", name1);

    setbuf(stdin, NULL);
    printf("\nSecond name: ");
    scanf("%[^\n]", name2);
    
    strcpy(name3, name2);
    printf("\nname3: %s", name3);
    
    strncpy(name4, name3, 5);
    printf("\nname4: %s", name4);

    //printf("\nSize of first name: %zu", strlen(nome1)); //zu para size_t
    //printf("\nTamanho do segundo nome: %d", (int) strlen(nome2));

    strncpy(name5, name1, 3);
    printf("\nname1: %s", name1);
    printf("\nname2: %s", name2);
    printf("\nname3: %s", name3);
    printf("\nname4: %s", name4);
    printf("\nname5: %s", name5);
    strcat(name1, name2);
    printf("\nname1: %s", name1);
    
    strncat(name4, name5, 3);
    printf("\nname4: %s", name4);
    
    return 0;
}

当我运行代码时,我得到以下输出:

First name: apple

Second name: elefant

name3: elefant
name4: elefa
name1: apple
name2: elefant
name3: elefant
name4: elefa
name5: app|�
name1: appleelefant
name4: elefaapp

为什么name5 得到app|� 而不是仅仅得到app?此外,有时我得到最后一个name4,它是name4name5 的串联,为elefaapp|�。谁能解释一下这种奇怪的行为吗?

我已经搜索并阅读了函数文档,但我对此一无所知。

【问题讨论】:

  • 你忘了空终止name5,所以它包含'a''b''c',后面是垃圾。在strncat 调用后添加name5[3] = '\0'; 以修复它。
  • strncpy 不会在字符串中添加空终止符,因此您会在name5 中得到垃圾。在任何 strncpy 尝试之前使用 memset(dest, '\0', sizeof(dest));
  • 正如strncpy 文档中所说,“...最多复制 n 个字节的 src。警告:如果 src 的前 n 个字节中没有空字节,则放置的字符串in dest 不会以 null 结尾。”您需要输入一个终止空字符。
  • @DaltonCézane 你从未将name5 传递给fgetsscanf。问题不在于name1。这是name5name5 中的初始值未定义。然后,您将其传递给长度为 3 的 strncpy。这定义了 name5 的前三个值,其余值保留其原始未定义值。所以在调用之后,name5 包含三个已定义的值,后跟 27 个未定义的值。如果要使用strncpy 设置name5,则必须确保将最后一个复制值之后的第一个值设置为'\0'。你忘了这样做。
  • 问题不是name1或者是如何获取的。问题是name5 及其未定义的内容。

标签: c string.h strncmp


【解决方案1】:

来自文档:

https://www.cplusplus.com/reference/cstring/strncpy/

如果 source 长于 num,则不会在目标末尾隐式附加空字符。因此,在这种情况下,destination 不应被视为以 null 结尾的 C 字符串(这样读取它会溢出)。

一般情况下,使用strncpy时需要手动添加一个'\0'来终止字符串

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2012-06-14
    • 2011-01-01
    • 2016-04-03
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多