How to avoid buffer overflow using scanf

#include <stdio.h>
#include <stdlib.h>

int main(int argc, char **argv) {
    char first_name[20];
    char last_name[20];
    int student_num;
    char debts[1];

    printf("Enter name:");
    scanf("%s", first_name);
    printf("Enter lastname:");
    scanf("%s", last_name);
    printf("Enter six bits length student ID:");
    scanf("%d", &student_num);
    printf("Do you have debts for university [Y/N]?");
    scanf("%s", debts);

    printf("\nYour name is %s %s.\n", first_name, last_name);
    printf("Your Student ID is %d.\n", student_num);
    printf("Debts: %s.\n", debts);
    return (EXIT_SUCCESS);

How to avoid buffer overflow in this code? I want my code to produce such an output:

Enter name:Enescekilokoneyasharrontannamyantoniaaquin
Enter lastname:Basenau
Enter six bits length student ID:456789
Do you have debts for university [Y/N]?YES

Your name is **Enescekilokoneyashar** (only 20 bits from name input) *Basenau*.
Your Student ID is **393299**.
Debts: **Y**.

Process returned -1073741819 (0xC0000005)   execution time : 36.336 s
Press any key to continue.

I have tried to use:

scanf("%19s", first_name);

But it does not work as I expect. I need to find some another way to validate input parameters to prevent buffer overflow attack and limit input to buffers size.

asked on Stack Overflow Oct 15, 2020 by Adomas Ba • edited Oct 15, 2020 by anastaciu

2 Answers


You can maintain the use of scanf but you need to limit the size of what it can take to the size of the destination buffer, something like:

scanf(" %19[^\n]", first_name); //last destination buffer element is for null byte

Note that this specifier can parse spaces so you can take an input with more than one word.

It will, however, leave a \n character in the stdin buffer, or the remaining characters that were not parsed in case you input a larger string, so you need to clear it every time you want to parse a new input, you can make a handy function that you can call when you need such clearence, making it a pattern:

void clear_buffer(){
    int c;
    while ((c = getchar()) != '\n' && c != EOF){

Your char debts[1] buffer is also problematic, it's too small to store a string, it needs to have at least 2 characters to be able to store the null terminator:

char debts[2];

And the call will be:

scanf(" %1[^\n]", debts);

Lastly you should verify the return of scanf, for instance, in scanf("%d", &student_num), if you input alphabetical characters instead of digits, the function will fail to parse and return 0, you can also make it parse at most 6 digits, something along the lines of:

if(scanf("%6d", &student_num) == 0){ // %6d limit the input to 6 digits
    //handle error

Live demo

answered on Stack Overflow Oct 15, 2020 by anastaciu • edited Oct 15, 2020 by anastaciu

If you are on windows you can use scanf_s() as described in the Microsoft documentation here. There is also an example given:

char s[10];
scanf_s("%9s", s, (unsigned)_countof(s));
answered on Stack Overflow Oct 15, 2020 by Michael

User contributions licensed under CC BY-SA 3.0