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

strncpy only copying 16 bytes from one string to another

提问人:Otávio Zampar 提问时间:12/7/2021 更新时间:12/7/2021 访问量:139

问:

所以我有这个函数,现在,它从输入 .txt 中获取一个字符串,并使用 strncpy() 通过引用将其传递给字符串 str。但是当我尝试在函数外部调用字符串时,如果它尝试复制超过 16 个(末尾带有“/0”的 15),我根本得不到任何东西。

这是我的功能:

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;
}

我的主线也很简单

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;
}

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

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

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

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

C 字符串 按引用传递

评论

1赞 Ted Lyngmo 12/7/2021
fgets(a, size + 1, arquivo);- 如果您读取字符长的字符串,这将使程序具有未定义的行为。然后,它将写入越界。它应该是 - 您还应该检查 的返回值。它可能会返回以指示失败。size\0fgets(a, size, arquivo);fgetsNULL
1赞 Ted Lyngmo 12/7/2021
好的,但至少你少了一个潜在的崩溃。
1赞 Gerhardh 12/7/2021
检查您的返回值!!您还会忽略 的返回值。这些价值观不仅仅是为了娱乐。fgets
1赞 Lundin 12/7/2021
strncpy是其中之一,本质上是被破坏的古代 C 标准函数,在现代 C 编程中永远不应该用于任何目的。请参阅 strcpy 危险吗,应该用什么来代替?
1赞 chux - Reinstate Monica 12/7/2021
Otávio Zampar,提示:启用所有编译器警告。这将为您提供有关代码中的错误和弱点的快速反馈。

答:

-1赞 0___________ 12/7/2021 #1
strncpy(str, a, 16);
strncpy(dest, src, length);

length是复制的最大 s 数。因此,在您的情况下,它不会超过 16 秒charchar

评论

0赞 Otávio Zampar 12/7/2021
是的,理想情况下我会将长度作为大小(该输入中的 36),但是当我这样做时,我没有从 printf(“\n%s”, str) 得到任何响应;所以 Max 最终是 Beeing 16(由蛮力计算)