C
Completed
-
Section 1: Getting Started
-
Section 2: Core Syntax
-
Section 3: Functions
-
Section 4: Arrays and Strings
-
Section 5: Pointers
-
Section 6: Memory Management
-
Section 7: Structures and Unions
-
Section 8: The Preprocessor and Build Process
-
Section 9: Standard Library: stdio.h
-
Section 10: Standard Library: stdlib.h
-
Section 11: Standard Library: string.h
-
Section 12: Standard Library: ctype.h and wctype.h
-
Section 13: Standard Library: math.h, complex.h, fenv.h, tgmath.h
-
Section 14: Standard Library: Type and Limit Headers
-
Section 15: Standard Library: Error Handling and Debugging
-
Section 16: Standard Library: Localization and Encoding
-
Section 17: Standard Library: time.h
-
Section 18: Standard Library: Concurrency (C11)
-
Section 19: POSIX and System Programming (unistd.h)
-
Section 20: More Data Structures
-
Section 21: Algorithms in C
-
Section 22: Bitwise Operations
-
Section 23: Command-Line Programs
-
Section 24: Debugging and Best Practices
-
Section 25: Compiler and Language Internals
-
Section 26: Embedded and Cross-Platform Considerations
-
Section 27: Networking Basics
-
Section 28: Practical Projects
-
Section 29: Interview Practice
-
Section 30: C23 Modern Features
-
Section 31: More Practice and Review
191: Building Interactive Command-Line Prompts
Think of an interactive command-line prompt like a drive-thru ordering window. The employee doesn't just stand there in silence; they ask a specific question ("Welcome to Burger-C, can I take your order?"), they wait for your response, and then—this is the important part—they validate what you said. If you tell them you want a "spaceship," they don't just crash the restaurant; they tell you that's not on the menu and ask again. In C, if we don't handle our prompts and buffers carefully, our program is the restaurant that crashes the moment a user types something unexpected.
Here is how that drive-thru logic maps to the code we're writing:
- The Question: This is your
printf. It needs to be clear and end with a prompt character (like>or:) so the user knows the program isn't frozen. - The Listening: This is where we use
fgets. I'm steering you away fromscanffor strings becausescanfis like a drive-thru employee who stops listening the second you pause for breath (a space character), leaving the rest of your order to clog up the system. - The Validation: This is where we check the input against our expected values using
strcmpor by checking for specific characters. - The Loop: This is the "keep asking until it's right" phase, usually handled by a
whileloop.
The Danger of the Trailing Newline
When you use fgets, it does something that often catches people off guard: it captures the \n (the Enter key) at the end of the string. If you ask a user for their name and they type "Alice", fgets stores "Alice\n". If you then try to compare that to the string "Alice", the comparison will fail. It's a tiny detail, but it's the source of a thousand bugs.
#include <stdio.h>
#include <string.h>
int main() {
char choice[10];
printf("Enter 'yes' to continue: ");
fgets(choice, sizeof(choice), stdin);
// This is the trick I always use to strip the newline
choice[strcspn(choice, "\n")] = 0;
if (strcmp(choice, "yes") == 0) {
printf("Moving forward!\n");
} else {
printf("You said: %s (which is not 'yes')\n", choice);
}
return 0;
}
Building a Robust Command Loop
In a real tool, you don't want the program to end just because the user made one typo. You want a loop that keeps the prompt alive until a specific "exit" command is issued. I've found that the cleanest way to do this is by using a flag variable. This keeps your loop condition simple and gives you a clear way to break out from anywhere inside the logic.
#include <stdio.h>
#include <string.h>
#include <stdbool.h>
int main() {
char input[64];
bool running = true;
while (running) {
printf("\n[System Admin] Enter command (status, reset, quit): ");
if (fgets(input, sizeof(input), stdin) == NULL) break;
input[strcspn(input, "\n")] = 0;
if (strcmp(input, "status") == 0) {
printf("All systems operational.\n");
} else if (strcmp(input, "reset") == 0) {
printf("Resetting configuration... Done.\n");
} else if (strcmp(input, "quit") == 0) {
printf("Shutting down.\n");
running = false;
} else {
printf("Unknown command: '%s'. Try again.\n", input);
}
}
return 0;
}
Notice how I used sizeof(input) inside fgets. Never hard-code the buffer size in the function call. If you decide to increase your buffer from 64 to 128 bytes later, you only want to change it in one place, not in every single fgets call across your project.
📋 Practical Task
Build a Secure User Profile Configuration Tool
Your task is to create a program that prompts a user to set up a profile. The program must follow these requirements:
- Username: Prompt the user for a username. If the username is shorter than 3 characters, tell them it's too short and prompt them again.
- Access Level: Prompt the user to enter an access level (either "Admin" or "Guest"). If they enter anything else, explain that only these two levels are permitted and loop the prompt until they provide a valid one.
- Confirmation: Once both are collected, print a summary:
"Profile Created: [Username] with [Access Level] privileges." - Robustness: Use
fgetsand ensure all trailing newlines are removed before performing your checks.
There are no comments for now.