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
218: Building a Simple Text-Based Calculator
When you first start building a calculator in C, you'll likely run into a frustrating wall. You'll write a prompt asking for a number, then a prompt asking for an operator, but the program will seemingly "skip" the operator input and jump straight to the final result. You'll check your logic ten times, and it will look perfect. You might even think your keyboard is broken or that C has a weird bug.
The "Invisible Newline" that breaks your input
The misconception here is that scanf consumes everything you type. It doesn't. When you type a number and hit Enter, you aren't just sending the number to the program; you're sending the number and a newline character (\n). scanf("%lf", &num1) reads the number, but it leaves that \n sitting right there in the input buffer.
When your code hits the next scanf("%c", &op), it doesn't wait for you to type. It looks at the buffer, sees the leftover \n, says "Aha! A character!", and assigns that newline to your operator variable. Your program didn't skip the step; it just processed the "Enter" key from your previous input as the operator.
The magic space in scanf
I've seen developers spend hours trying to fix this with fflush(stdin) (which is undefined behavior on many systems) or complex getchar() loops. The professional way to handle this in a simple CLI tool is actually a single space character inside the format string.
// The wrong way
scanf("%c", &op);
// The right way
scanf(" %c", &op);
That leading space in " %c" tells C to discard all leading whitespace—including tabs, spaces, and that pesky newline character—until it finds the first non-whitespace character. It's a tiny detail, but it's the difference between a program that feels broken and one that feels polished.
Turning characters into math with switch
Once we've actually captured the operator, we need a way to map that character to a mathematical operation. While a chain of if-else statements works, it's clunky. Since we are comparing a single char against constant values, a switch statement is the idiomatic choice here. It's cleaner and tells anyone reading your code exactly what the intent is: "Pick one of these paths based on the symbol."
double result;
switch (op) {
case '+':
result = num1 + num2;
break;
case '-':
result = num1 - num2;
break;
case '*':
result = num1 * num2;
break;
case '/':
// We'll handle the danger here in a moment
result = num1 / num2;
break;
default:
printf("Error: Invalid operator!");
return 1;
}
Preventing the division-by-zero crash
As a software engineer, I don't care if the code works when the user does what they're told; I care about what happens when the user tries to break it. Dividing by zero is the classic way to crash a calculator. In C, dividing a floating-point number by zero might result in inf (infinity), but depending on the environment and the data types, it can lead to undefined behavior or crashes.
I always recommend wrapping the division logic in a simple guard clause. Don't just perform the math; verify the divisor first. It's a habit that will save you from countless production bugs in the future.
case '/':
if (num2 == 0) {
printf("Error: Division by zero is undefined.\n");
return 1;
}
result = num1 / num2;
break;
By combining the buffer-clearing space, a switch block for clean routing, and basic input validation, you move from writing a "script" to building a robust little piece of software.
📋 Practical Task
Exercise: Building a Robust Four-Function Calculator
Write a complete C program that implements a text-based calculator. Your program must meet the following technical requirements:
- Input Sequence: Prompt the user for the first number (
double), then the operator (char), then the second number (double). - The Buffer Fix: Ensure your operator
scanfhandles the trailing newline from the first number input so the program doesn't skip the prompt. - Operation Logic: Use a
switchstatement to handle addition (+), subtraction (-), multiplication (*), and division (/). - Safety Check: Implement a check specifically for division by zero. If the user attempts to divide by 0, print a clear error message and terminate the program with a non-zero exit code.
- Invalid Input: If the user enters an operator other than the four specified, print an "Invalid Operator" message.
- Precision: Print the final result formatted to 2 decimal places.
There are no comments for now.