strncpy 仅将 16 个字节从一个字符串复制到另一个

Posted

技术标签:

【中文标题】strncpy 仅将 16 个字节从一个字符串复制到另一个【英文标题】:strncpy only copying 16 bytes from one string to another 【发布时间】:2022-01-12 13:16:01 【问题描述】:

所以我现在有这个函数,它从 input.txt 中获取一个字符串,并使用 strncpy() 通过引用将其传递给字符串 str。但是当我尝试在函数外部调用字符串时,如果它尝试复制超过 16 个(15 个末尾带有 '/0'),我什么也得不到。

这是我的功能:

int openFile(char *str)
    FILE *arquivo;
    arquivo = fopen("input.txt", "r");
    if (arquivo == NULL)
        return 1; // couldnt open input.txt
    

    fseek(arquivo, 0, SEEK_END);
    int size = ftell(arquivo);
    rewind(arquivo);

    char *a = malloc(sizeof(char) * size); // enough for 'size' chars
    size_t buffer_len = sizeof(char) * size; // sizeof(a) returns sizeof(a as pointer), so uh.. dont
    printf("%d %d %d %d\n", sizeof(char), sizeof(a), size, buffer_len); // just to test what it's getting

    fgets(a, size + 1, arquivo);
    printf( "%s, %d" , a, size);

    realloc(str, sizeof(char) * size); // just in case there isnt enough space in str
    strncpy(str, a, 16); // error in THIS LINE doesnt copy more than 16 bytes
    // memmove(str, a, 16); //not a problem with strncpy, memmove gives the same problem
    // str[buffer_len - 1] = '\0';

    fclose(arquivo);

    free(a);
    return 0;

我的 main 也很简单

int main()

    char *str;

    if(openFile(str)) // if openFile return 1, error opening file
        printf("error opening file.\n");
        return 0;
    
        
    printf("\n%s", str);
    free(str);
    return 0;

最后是输入/输出(输入 = MEEUMOCSHMSC1T*AGU0A***L2****T*****A):

1 4 36 36
MEEUMOCSHMSC1T*AGU0A***L2****T*****A, 36
MEEUMOCSHMSC1T*A­

它是一个密码,这就是输入如此混乱的原因;

最后的“”是我猜的字符串的一部分,它每次都会改变,当我用 '\0' 替换 str[15] 时它消失了;

【问题讨论】:

fgets(a, size + 1, arquivo); - 如果您读取一个 size 字符长的字符串,这会使程序具有未定义的行为。然后它将写入\0 越界。它应该是fgets(a, size, arquivo); - 您还应该检查来自fgets 的返回值。它可能返回NULL 表示失败。 好的,但至少你减少了一次潜在的崩溃。 检查你的返回值!!你也忽略了fgets的返回值。这些价值观不仅仅是为了娱乐。 strncpy 是其中之一,它天生就被破坏了古老的 C 标准函数,在现代 C 编程中不应该用于任何目的。见Is strcpy dangerous and what should be used instead? Otávio Zampar,提示:启用所有编译器警告。这将为您提供有关代码中的错误和弱点的快速反馈。 【参考方案1】:
strncpy(str, a, 16);
strncpy(dest, src, length);

length最大chars 复制。所以在你的情况下它不会超过 16 个chars

【讨论】:

是的,理想情况下,我会将长度设置为大小(输入中为 36),但是当我这样做时,我没有得到 printf("\n%s", str); 的任何响应;所以最大值最终是 16 (通过蛮力计算)

以上是关于strncpy 仅将 16 个字节从一个字符串复制到另一个的主要内容,如果未能解决你的问题,请参考以下文章

C 标准库 - string.h之strncpy使用

strncpy函数使用

strcpy与strncpy

strcnpy用来复制字符串的前n个字符

memcpy 仅通过 C++ 复制一个字节

strncpy()用于在MFC中复制字符串时截断的数据[重复]