DevAcademia
C++C#CPythonJava
  • C Basics

  • Introduction to C
  • Getting Started with C
  • C Syntax
  • C Output
  • C Comments
  • C Variables
  • C Data Types
  • C Constants
  • C Operators
  • C Booleans
  • C If...Else Statements
  • C Switch Statement
  • C While Loops
  • C For Loops
  • C Break and Continue
  • C Strings
  • C User Input
  • C Memory Address
  • C Pointers
  • C Files
  • C Functions

  • C Functions
  • C Function Parameters
  • C Scope
  • C Function Declaration
  • C Recursion
  • C Math Functions
  • C Structures

  • C Structures
  • C Structs & Pointers
  • C Unions
  • C Enums

  • C Enums
  • C Memory

  • C Allocate Memory
  • C Access Memory
  • C Reallocate Memory
  • C Deallocate Memory
  • C Structs and Memory
  • C Memory Example
  • C Quiz

  • C Quiz
  • C Basics

  • Introduction to C
  • Getting Started with C
  • C Syntax
  • C Output
  • C Comments
  • C Variables
  • C Data Types
  • C Constants
  • C Operators
  • C Booleans
  • C If...Else Statements
  • C Switch Statement
  • C While Loops
  • C For Loops
  • C Break and Continue
  • C Strings
  • C User Input
  • C Memory Address
  • C Pointers
  • C Files
  • C Functions

  • C Functions
  • C Function Parameters
  • C Scope
  • C Function Declaration
  • C Recursion
  • C Math Functions
  • C Structures

  • C Structures
  • C Structs & Pointers
  • C Unions
  • C Enums

  • C Enums
  • C Memory

  • C Allocate Memory
  • C Access Memory
  • C Reallocate Memory
  • C Deallocate Memory
  • C Structs and Memory
  • C Memory Example
  • C Quiz

  • C Quiz

Loading C tutorial…

Loading content
C BasicsTopic 41 of 64
←PreviousPrevNextNext→

C User Input

Introduction to User Input in C

User input is a fundamental aspect of interactive programs. In C, there are several functions available for reading input from the user, each with its own characteristics and use cases.

Understanding how to properly handle user input is crucial for creating robust applications that can handle various types of data and prevent common issues like buffer overflows.

The scanf() Function

scanf() is the most commonly used function for reading formatted input in C. It reads data from stdin (standard input) and stores it according to the specified format.

Syntax: int scanf(const char *format, ...);

The function returns the number of successfully read items, or EOF on error.

Example
#include <stdio.h>

int main(void) {
    int age;
    float height;
    char name[50];
    
    printf("Enter your name: ");
    scanf("%49s", name); // Reads a single word (bounded)
    
    printf("Enter your age and height: ");
    int itemsRead = scanf("%d %f", &age, &height);
    
    // Output without using \n in string literals
    puts("");
    printf("Hello %s!", name);
    puts("");
    printf("You are %d years old and %.2f meters tall.", age, height);
    puts("");
    printf("Items successfully read: %d", itemsRead);
    puts("");
    
    return 0;
}
Output
Enter your name: John
Enter your age and height: 25 1.75

Hello John!
You are 25 years old and 1.75 meters tall.
Items successfully read: 2

Limitations of scanf()

While scanf() is convenient, it has several limitations:

1. It stops reading at whitespace, making it unsuitable for reading strings with spaces

2. It doesn't perform bounds checking unless you provide a field width

3. It can leave unwanted characters (like newlines) in the input buffer

4. It requires precise format matching

⚠️ Warning: Always specify a maximum field width for %s (e.g., %19s for a 20-byte buffer). Unbounded %s can overflow and corrupt memory.
Example
#include <stdio.h>

int main(void) {
    char city[20];
    
    printf("Enter your city: ");
    scanf("%19s", city); // Will only read until first space
    
    printf("City: %s", city);
    puts("");
    
    // Safer bounded read to prevent overflow in smallBuffer
    char smallBuffer[5];
    printf("Enter a short word (max 4 chars): ");
    scanf("%4s", smallBuffer); // Bounded — leaves room for '\0'
    printf("Buffer content: %s", smallBuffer);
    puts("");
    
    // DANGER (do not enable): removing the width specifier can overflow
    // scanf("%s", smallBuffer); // Potential buffer overflow
    
    return 0;
}
Output
Enter your city: New York
City: New
Enter a short word (max 4 chars): ThisIsALongString
Buffer content: This

The fgets() Function

fgets() is a safer alternative for reading strings. It reads a line of input and includes the newline character, and it allows you to specify the maximum number of characters to read.

Syntax: char *fgets(char *str, int n, FILE *stream);

It returns the string pointer on success, or NULL on error or end of file.

Example
#include <stdio.h>
#include <string.h>

int main(void) {
    char name[50];
    
    printf("Enter your full name: ");
    if (fgets(name, sizeof(name), stdin)) {
        name[strcspn(name, "\n")] = '\0'; // remove trailing newline if present
        printf("Hello, %s!", name);
        puts("");
    }
    
    // Reading another line
    char address[100];
    puts("Enter your address (press Enter when done):");
    if (fgets(address, sizeof(address), stdin)) {
        address[strcspn(address, "\n")] = '\0';
        printf("Address: %s", address);
        puts("");
    }
    
    return 0;
}
Output
Enter your full name: John Doe
Hello, John Doe!
Enter your address (press Enter when done):
123 Main Street, City, State
Address: 123 Main Street, City, State

Mixing scanf() and fgets() (Clearing Leftover Newlines)

When you use scanf() and then fgets(), the newline left in the input buffer by pressing Enter can cause fgets() to read an empty line. To avoid this, consume the leftover characters (usually the trailing '\n') before calling fgets().

Example
#include <stdio.h>

int main(void) {
    int n;
    char line[64];

    printf("Enter an integer: ");
    if (scanf("%d", &n) == 1) {
        int ch; // consume the rest of the line, including the newline
        while ((ch = getchar()) != '\n' && ch != EOF) { }
    }

    printf("Enter a sentence: ");
    if (fgets(line, sizeof line, stdin)) {
        printf("You typed: %s", line);
    }
    return 0;
}

Reading Different Data Types

For reading different data types, you can combine fgets() with conversion functions like atoi(), atof(), or strtol()/strtod() for better error handling and safety.

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

int main(void) {
    char input[100];
    int age;
    double salary;
    
    // Reading and converting integers
    printf("Enter your age: ");
    fgets(input, sizeof(input), stdin);
    age = atoi(input); // Simple conversion (no error reporting)
    
    // Reading and converting floating-point numbers
    printf("Enter your salary: ");
    fgets(input, sizeof(input), stdin);
    salary = atof(input); // Simple conversion (no error reporting)
    
    printf("Age: %d, Salary: $%.2f", age, salary);
    puts("");
    
    // Better error handling with strtol
    printf("Enter a number: ");
    fgets(input, sizeof(input), stdin);
    char *endptr;
    long number = strtol(input, &endptr, 10);
    
    if (endptr == input) {
        puts("No digits were found");
    } else if (*endptr != '\0' && *endptr != '\n') {
        printf("Further characters after number: %s", endptr);
        puts("");
    } else {
        printf("Number: %ld", number);
        puts("");
    }
    
    return 0;
}
Output
Enter your age: 30
Enter your salary: 50000.50
Age: 30, Salary: $50000.50
Enter a number: 42abc
Further characters after number: abc

Input Validation

Proper input validation is essential for creating robust programs. You should always validate that input meets expected criteria before using it.

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

int main(void) {
    char input[100];
    int valid = 0;
    int number = 0;
    
    while (!valid) {
        printf("Enter a positive integer: ");
        if (!fgets(input, sizeof(input), stdin)) return 1;
        
        // Check if input is a valid positive integer
        valid = 1;
        for (int i = 0; input[i] != '\0' && input[i] != '\n'; i++) {
            if (!isdigit((unsigned char)input[i])) {
                valid = 0;
                puts("Invalid input. Please enter digits only.");
                break;
            }
        }
        
        if (valid) {
            number = atoi(input);
            if (number <= 0) {
                valid = 0;
                puts("Number must be positive.");
            }
        }
    }
    
    printf("You entered: %d", number);
    puts("");
    
    return 0;
}
Output
Enter a positive integer: abc
Invalid input. Please enter digits only.
Enter a positive integer: -5
Invalid input. Please enter digits only.
Enter a positive integer: 0
Number must be positive.
Enter a positive integer: 42
You entered: 42

Best Practices for User Input

1. Use fgets() instead of gets() or unbounded scanf() for reading strings

2. Always check the return value of input functions

3. Validate input before using it

4. Use appropriate conversion functions with error checking (strtol/strtod for robust parsing)

5. Be aware of buffer sizes and prevent overflows (use field widths with scanf)

6. Clear the input buffer when mixing scanf() and fgets()

7. Provide clear prompts and error messages

Test your knowledge: C User Input
Quiz Configuration
8 of 8 questions
Sequential
Previous allowed
Review enabled
Early close allowed
Estimated time: 10 min
C BasicsTopic 41 of 64
←PreviousPrevNextNext→