【发布时间】: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,提示:启用所有编译器警告。这将为您提供有关代码中的错误和弱点的快速反馈。
标签: c string pass-by-reference