我正在制作这个控制台应用程序,用户必须在其中输入内容。然而,当代码到达用户输入文件名的部分,然后使用 strcat 将其添加到文件路径中时,它会输出段错误。 完整代码如下:
int main(int argc, char *argv[])
{
char theFilePath[512];
char theIP[20];
char theFile[100];
char password[1];
char username[10];
printf("Username: ");
scanf("%s" , &username);
printf("Enter password: ");
scanf("%s", &password);
printf("Enter IP: ");
scanf("%d" , &theIP);
printf("Please specify the file: ");
scanf("%s" , &theFile);
strcat(theFilePath, "./passfiles/");
strcat(theFilePath, theFile);
strcat(theFilePath,".pf");
sprintf(theFilePath,"%s",theFilePath);
if (!(file_exist (theFilePath)))
{
printf("The file cannot be found in the path %s", theFilePath);
exit(EXIT_FAILURE);
} else
{
printf("The file exists!");
}
}
有什么想法为什么要这样做吗?
提前致谢!
最佳答案
您(至少)有几个问题。
首先,您通常不应该使用无界的 %s
是 scanf
,因为它不能防止缓冲区溢出(与 非常相似) >gets
,它在 C99 中已弃用并从 C11 中删除)。
当您的缓冲区小得可怜(例如char password[1]
)时,这一点就显得尤为重要,这意味着,使用空终止符,您的所有密码都必须为零字符长。现在我不是世界著名的安全研究人员,但我有理由相信该方案某处存在安全漏洞:-)
当需要用户输入时,有更安全的选项,例如可以找到 here 的函数,一种防止缓冲区溢出并提供有关用户尝试输入过多数据(并从中恢复)的信息。
第二个是依赖未初始化的内存。 theFilePath
变量未初始化,因此其中可能包含任意数据,但您使用 strcat
时期望它包含以 num 结尾的字符串。这是一个错误的假设,可以通过简单地将第一个 strcat
转换为 strcpy
来修复,或者因为它总是被设置为相同的初始值,所以将其作为一部分变量声明本身:
char theFilePath[512] = "./passfiles/";
<小时/>
顺便说一句,假设您使用的是现代 C 编译器,您最好在需要的地方声明变量,而不是全部在函数的顶部,这意味着该声明应该放在哪里当前(错误的)strcat
当前是。本地化您的声明和使用可以极大地提高可读性。
您可能还想考虑一下该语句的用处:
sprintf(theFilePath,"%s",theFilePath);
即使它有效,它实际上是一个无操作,因为它所做的只是将一些数据复制到与当前存在的完全相同的位置。无论如何,它不能保证正常工作,因为标准在C11 7.21.6.6./2
中明确指出:
If copying takes place between objects that overlap, the behavior is undefined.
关于c - 为什么某部分代码会输出Segmentation Failure?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/42059105/