C provides several ways to read string input from the user. Each method has different behavior with spaces, safety concerns, and use cases.
Input Methods Comparison
| Function | Includes Spaces? | Buffer Safe? | Stops At | Header |
|---|---|---|---|---|
scanf("%s") | No | No | Whitespace | <stdio.h> |
gets() | Yes | No (Dangerous!) | Newline | <stdio.h> |
fgets() | Yes | Yes | Newline (or max length) | <stdio.h> |
scanf("%[^\n]") | Yes | No | Newline | <stdio.h> |
Method 1: scanf("%s") – Single Word Only
#include <stdio.h>
int main() {
char name[50];
printf("Enter your name: ");
scanf("%s", name); // No & needed (array name is address)
printf("Hello, %s!\n", name);
return 0;
}
Input/Output:
Enter your name: John Doe Hello, John!
⚠️ Only reads until the first space. "Doe" is ignored.
Method 2: fgets() – Safest Method (Recommended)
#include <stdio.h>
#include <string.h>
int main() {
char sentence[100];
printf("Enter a sentence: ");
fgets(sentence, sizeof(sentence), stdin); // Reads up to 99 chars + '\0'
// Remove trailing newline character
size_t len = strlen(sentence);
if(len > 0 && sentence[len-1] == '\n') {
sentence[len-1] = '\0';
}
printf("You entered: %s\n", sentence);
return 0;
}
Input/Output:
Enter a sentence: Hello, this is C programming! You entered: Hello, this is C programming!
Method 3: scanf("%[^\n]") – Read Until Newline
#include <stdio.h>
int main() {
char line[200];
printf("Enter a line: ");
scanf(" %[^\n]", line); // Space before % clears leftover newline
printf("You entered: %s\n", line);
return 0;
}
Input/Output:
Enter a line: This is a complete line with spaces You entered: This is a complete line with spaces
⚠️ Not buffer-safe. Can overflow if input exceeds array size.
Example 1: Multiple String Inputs with fgets
#include <stdio.h>
#include <string.h>
void safeInput(char *buffer, int size) {
fgets(buffer, size, stdin);
// Remove newline
size_t len = strlen(buffer);
if(len > 0 && buffer[len-1] == '\n') {
buffer[len-1] = '\0';
}
}
int main() {
char firstName[30];
char lastName[30];
char city[40];
printf("Enter first name: ");
safeInput(firstName, sizeof(firstName));
printf("Enter last name: ");
safeInput(lastName, sizeof(lastName));
printf("Enter city: ");
safeInput(city, sizeof(city));
printf("\n--- User Info ---\n");
printf("Name: %s %s\n", firstName, lastName);
printf("City: %s\n", city);
return 0;
}
Example 2: Reading Strings with scanf (Multiple Words)
#include <stdio.h>
int main() {
char firstName[30];
char lastName[30];
printf("Enter first and last name: ");
scanf("%s %s", firstName, lastName); // Reads two words
printf("First: %s, Last: %s\n", firstName, lastName);
return 0;
}
Input/Output:
Enter first and last name: John Smith First: John, Last: Smith
Example 3: Mixing scanf and fgets (The Newline Problem)
#include <stdio.h>
#include <string.h>
int main() {
int age;
char name[50];
printf("Enter your age: ");
scanf("%d", &age);
// Clear the newline left in buffer
while(getchar() != '\n'); // Consume leftover newline
printf("Enter your full name: ");
fgets(name, sizeof(name), stdin);
// Remove newline from fgets
size_t len = strlen(name);
if(len > 0 && name[len-1] == '\n') {
name[len-1] = '\0';
}
printf("Age: %d, Name: %s\n", age, name);
return 0;
}
Input/Output:
Enter your age: 25 Enter your full name: Alice Johnson Age: 25, Name: Alice Johnson
Example 4: Limiting Input Length for Safety
#include <stdio.h>
int main() {
char username[11]; // Max 10 chars + null terminator
printf("Enter username (max 10 chars): ");
scanf("%10s", username); // Reads only 10 characters
printf("Username: %s\n", username);
// fgets version with limit
char password[21];
printf("Enter password (max 20 chars): ");
fgets(password, sizeof(password), stdin);
// Clear any remaining input if too long
if(strlen(password) == 20 && password[19] != '\n') {
while(getchar() != '\n'); // Flush excess
} else {
// Remove newline
size_t len = strlen(password);
if(len > 0 && password[len-1] == '\n') {
password[len-1] = '\0';
}
}
printf("Password accepted\n");
return 0;
}
Example 5: Reading Until a Delimiter
#include <stdio.h>
int main() {
char data[200];
printf("Enter data (stop at comma): ");
scanf("%[^,]", data); // Reads until comma
printf("Data before comma: %s\n", data);
return 0;
}
Input/Output:
Enter data (stop at comma): Apple,Banana,Orange Data before comma: Apple
Example 6: Reading Multiple Lines Until EOF
#include <stdio.h>
#include <string.h>
int main() {
char line[200];
int lineCount = 0;
printf("Enter multiple lines (Ctrl+D to end):\n");
while(fgets(line, sizeof(line), stdin) != NULL) {
lineCount++;
// Remove newline
size_t len = strlen(line);
if(len > 0 && line[len-1] == '\n') {
line[len-1] = '\0';
}
printf("Line %d: %s\n", lineCount, line);
}
printf("Total lines: %d\n", lineCount);
return 0;
}
Common Pitfalls and Solutions
Problem 1: Leftover Newline After scanf
// ❌ WRONG - fgets reads leftover newline
int num;
char text[50];
scanf("%d", &num);
fgets(text, 50, stdin); // Reads empty string (just newline)
// ✅ SOLUTION 1 - Clear buffer
scanf("%d", &num);
while(getchar() != '\n'); // Clear newline
fgets(text, 50, stdin);
// ✅ SOLUTION 2 - Use getchar
scanf("%d", &num);
getchar(); // Consume newline
fgets(text, 50, stdin);
Problem 2: Buffer Overflow
// ❌ DANGEROUS - No length limit
char buffer[10];
scanf("%s", buffer); // Input "HelloWorld123" will overflow
// ✅ SAFE - Limit length
char buffer[10];
scanf("%9s", buffer); // Reads max 9 chars
fgets(buffer, sizeof(buffer), stdin); // Safe with fgets
Problem 3: gets() – Never Use This!
// ❌ NEVER USE gets() - It's removed from C11 char buffer[100]; gets(buffer); // DANGEROUS! No bounds checking // ✅ ALWAYS use fgets instead char buffer[100]; fgets(buffer, sizeof(buffer), stdin);
Input Function Safety Ratings
| Function | Safety Rating | Recommendation |
|---|---|---|
fgets() | ✅ Safe | Use this |
scanf("%s") | ⚠️ Limited | Use with width specifier: %9s |
gets() | ❌ Dangerous | Never use |
scanf("%[^\n]") | ⚠️ Limited | No built-in bounds checking |
Quick Reference Guide
| Task | Code Example |
|---|---|
| Read single word | scanf("%s", buffer) |
| Read line safely | fgets(buffer, size, stdin) |
| Read line + remove newline | fgets(buf, size, stdin); buf[strcspn(buf, "\n")] = 0 |
| Read limited chars | scanf("%9s", buffer) |
| Clear input buffer | while(getchar() != '\n'); |
| Read until comma | scanf("%[^,]", buffer) |
| Read multiple lines | while(fgets(buf, size, stdin)) |
Best Practice Template
#include <stdio.h>
#include <string.h>
// Reusable safe string input function
void safeStringInput(char *buffer, int size) {
fgets(buffer, size, stdin);
// Remove trailing newline
buffer[strcspn(buffer, "\n")] = '\0';
// Clear excess input if line was too long
if(strlen(buffer) == size - 1 && buffer[size-2] != '\n') {
while(getchar() != '\n');
}
}
int main() {
char name[50];
char address[100];
char comment[200];
printf("Enter name: ");
safeStringInput(name, sizeof(name));
printf("Enter address: ");
safeStringInput(address, sizeof(address));
printf("Enter comment: ");
safeStringInput(comment, sizeof(comment));
printf("\n--- Results ---\n");
printf("Name: %s\n", name);
printf("Address: %s\n", address);
printf("Comment: %s\n", comment);
return 0;
}
Complete Guide to Core & Advanced C Programming Concepts (Functions, Strings, Arrays, Loops, I/O, Control Flow)
https://macronepal.com/bash/building-blocks-of-c-a-complete-guide-to-functions/
Explains how functions in C work as reusable blocks of code, including declaration, definition, parameters, return values, and modular programming structure.
https://macronepal.com/bash/the-heart-of-text-processing-a-complete-guide-to-strings-in-c-2/
Explains how strings are handled in C using character arrays, string manipulation techniques, and common library functions for text processing.
https://macronepal.com/bash/the-cornerstone-of-data-organization-a-complete-guide-to-arrays-in-c/
Explains arrays in C as structured memory storage for multiple values, including indexing, initialization, and efficient data organization.
https://macronepal.com/bash/guaranteed-execution-a-complete-guide-to-the-do-while-loop-in-c/
Explains the do-while loop in C, where the loop body executes at least once before checking the condition.
https://macronepal.com/bash/mastering-iteration-a-complete-guide-to-the-for-loop-in-c/
Explains the for loop in C, including initialization, condition checking, and increment/decrement for controlled iteration.
https://macronepal.com/bash/mastering-iteration-a-complete-guide-to-while-loops-in-c/
Explains the while loop in C, focusing on condition-based repetition and proper loop control mechanisms.
https://macronepal.com/bash/beyond-if-else-a-complete-guide-to-switch-case-in-c/
Explains switch-case statements in C, enabling multi-branch decision-making based on variable values.
https://macronepal.com/bash/mastering-conditional-logic-a-complete-guide-to-if-else-statements-in-c/
Explains if-else statements in C for decision-making and controlling program flow based on conditions.
https://macronepal.com/bash/mastering-the-fundamentals-a-complete-guide-to-arithmetic-operations-in-c/
Explains arithmetic operations in C such as addition, subtraction, multiplication, division, and operator precedence.
https://macronepal.com/bash/foundation-of-c-programming-a-complete-guide-to-basic-input-output/
Explains basic input and output in C using scanf and printf for interacting with users and displaying results.
Online C Code Compiler
https://macronepal.com/free-online-c-code-compiler-2/