如何消除从用户输入时的缓冲区溢出?
How to get rid of buffer overflow on taking input from user?
如何消除接收用户输入时的缓冲区溢出问题?通过使用 fgets 或 scanf?如果 fgets 那么它是如何防止的。作为初学者需要一些解释。
#include <stdio.h>
#include <stdlib.h>
int main(){
char choice[5];
char one='1', two='2', three='3';
printf("%c. Create new account\n",one);
printf("%c. Update information of existing account\n",two);
printf("%c. For transactions\n",three);
printf("Enter your choice: ");
// fgets(choice, sizeof choice, stdin); // This OR
// fgets(choice, 3, stdin); // This one
scanf("%s",choice); // This one
printf("Here is your choice: %s", choice);
return 0;
}
一个编写良好的程序会报告无效输入并显示一条易于理解的错误消息,而不是崩溃。
幸运的是,可以通过指定字段宽度或使用 a 标志来避免 scanf 缓冲区溢出。
当你指定一个字段宽度时,你需要提供一个char *类型的缓冲区(使用malloc或类似的函数)。你需要确保你指定的字段宽度不超过分配的字节数到你的缓冲区。
另一方面,如果您指定标志字符,则无需分配缓冲区——scanf 会为您完成。只需将指向 char * 类型的未分配变量的指针传递给 scanf,scanf 就会分配字符串需要的缓冲区,并且 return 会在您的参数中分配结果。这是 scanf 功能的 GNU 专用扩展。
这里是一个代码示例,它首先展示了如何通过分配缓冲区和指定字段宽度来安全地读取固定最大长度的字符串,然后展示了如何使用 a 标志安全地读取任意长度的字符串。
int main()
{
int bytes_read;
int nbytes = 100;
char *string1, *string2;
string1 = (char *) malloc (25);
puts ("Please enter a string of 20 characters or fewer.");
scanf ("%20s", string1);
printf ("\nYou typed the following string:\n%s\n\n", string1);
puts ("Now enter a string of any length.");
scanf ("%as", &string2);
printf ("\nYou typed the following string:\n%s\n", string2);
return 0;
}
关于这个示例程序,有几点需要注意。首先,请注意传递给第一个 scanf 调用的第二个参数是 string1,而不是 &string1。 scanf 函数需要指针作为其转换对应的参数,但字符串变量已经是一个指针(类型为 char *),因此您不需要在这里额外的间接层。但是,第二次调用 scanf 时确实需要它。我们向它传递了 &string2 而不是 string2 的参数,因为我们正在使用 a 标志,它分配一个足够大的字符串变量来包含它读取的字符,然后 returns 指向它的指针。
如何消除接收用户输入时的缓冲区溢出问题?通过使用 fgets 或 scanf?如果 fgets 那么它是如何防止的。作为初学者需要一些解释。
#include <stdio.h>
#include <stdlib.h>
int main(){
char choice[5];
char one='1', two='2', three='3';
printf("%c. Create new account\n",one);
printf("%c. Update information of existing account\n",two);
printf("%c. For transactions\n",three);
printf("Enter your choice: ");
// fgets(choice, sizeof choice, stdin); // This OR
// fgets(choice, 3, stdin); // This one
scanf("%s",choice); // This one
printf("Here is your choice: %s", choice);
return 0;
}
一个编写良好的程序会报告无效输入并显示一条易于理解的错误消息,而不是崩溃。
幸运的是,可以通过指定字段宽度或使用 a 标志来避免 scanf 缓冲区溢出。
当你指定一个字段宽度时,你需要提供一个char *类型的缓冲区(使用malloc或类似的函数)。你需要确保你指定的字段宽度不超过分配的字节数到你的缓冲区。
另一方面,如果您指定标志字符,则无需分配缓冲区——scanf 会为您完成。只需将指向 char * 类型的未分配变量的指针传递给 scanf,scanf 就会分配字符串需要的缓冲区,并且 return 会在您的参数中分配结果。这是 scanf 功能的 GNU 专用扩展。
这里是一个代码示例,它首先展示了如何通过分配缓冲区和指定字段宽度来安全地读取固定最大长度的字符串,然后展示了如何使用 a 标志安全地读取任意长度的字符串。
int main()
{
int bytes_read;
int nbytes = 100;
char *string1, *string2;
string1 = (char *) malloc (25);
puts ("Please enter a string of 20 characters or fewer.");
scanf ("%20s", string1);
printf ("\nYou typed the following string:\n%s\n\n", string1);
puts ("Now enter a string of any length.");
scanf ("%as", &string2);
printf ("\nYou typed the following string:\n%s\n", string2);
return 0;
}
关于这个示例程序,有几点需要注意。首先,请注意传递给第一个 scanf 调用的第二个参数是 string1,而不是 &string1。 scanf 函数需要指针作为其转换对应的参数,但字符串变量已经是一个指针(类型为 char *),因此您不需要在这里额外的间接层。但是,第二次调用 scanf 时确实需要它。我们向它传递了 &string2 而不是 string2 的参数,因为我们正在使用 a 标志,它分配一个足够大的字符串变量来包含它读取的字符,然后 returns 指向它的指针。