Fading Coder

One Final Commit for the Last Sprint

Home > Tech > Content

C Printf, Scanf, and Branching Logic Fundamentals

Tech 2

1. Formatted Output with printf()

The printf() function delivers formatted text to the standard output stream. The 'f' in its name signifies "format," meaning you can control how the output appears. Crucially, printf() does not append a newline automatically; the cursor remains at the end of the printed content. To move to the next line, include the escape sequence \n explicitly.

This function is declared in the standard header <stdio.h>, which must be included in your source file.

#include <stdio.h>

int main() {
    printf("Message one,\n message two");
    printf("There are %d participants", 3);
    return 0;
}

1.1 Format Specifiers (Placeholders)

Placeholders, marked by a percent sign, are substituted with corresponding argument values. Common specifiers include:

  • %c : character
  • %d or %i : signed decimal integer
  • %f : float/double floating-point (%lf for double in scanf)
  • %s : null-terminated string
  • %x or %X : hexadecimal integer (lowercase/uppercase)
  • %u : unsigned decimal integer
  • %p : pointer address
  • %% : literal percent sign

For length modifiers: %hd (short), %ld (long), %lld (long long), %zd (size_t). Floating-point variants include %e (scientific notation), %g (shortest representation).

The argument list must align exactly: with n placeholders, provide n additional arguments after the format string. Mismatched counts lead to undefined behavior, potentially printing garbage values from the stack.

int main() {
    printf("Inventory: %d %s\n", 4, "widgets");
    printf("%s contains %d items\n", "The box"); // Missing argument: prints random value for %d
    printf("Char: %c\n", 'Z');
    printf("Hex for 255: %x\n", 255);
    return 0;
}

1.2 Field Width and Precision

Specify a minimum field width between % and the specifier. By default, output is right-aligned; prepend a minus sign - for left alignment. If the value exceeds the specified width, the full value is printed.

int main() {
    printf("[%5d]\n", 42);   // [   42]
    printf("[%-5d]\n", 42);  // [42   ]
    printf("[%5d]\n", 10000); // [10000]
    return 0;
}

For floating-point values, the default precision is six decimal places. Control this using .precision, e.g., %.2f rounds to two decimal places. Combine width and precision: %8.2f allocates eight characters total, with two digits after the decimal point. Use %*.*f to take width and precision as integer arguments.

int main() {
    double val = 3.14159;
    printf("%.2f\n", val);       // 3.14
    printf("%8.2f\n", val);      //     3.14
    printf("%*.*f\n", 8, 2, val); //     3.14
    return 0;
}

Force a sign indicator with +: %+d prints +12 for positive numbers.

Limit string output with %.Ns: outputs at most N characters.

printf("%.5s", "HelloWorld"); // Hello

2. Formatted Input with scanf()

The scanf() function reads formatted input from stdin and assigns converted values to variables through pointers.

#include <stdio.h>

int main() {
    int score;
    printf("Enter score: ");
    scanf("%d", &score);
    printf("Recorded: %d\n", score);
    return 0;
}

On Microsoft compilers, scanf may trigger security warnings. Disable them globally by adding #define _CRT_SECURE_NO_WARNINGS at the very top of your source file, or insert this line into the newc++file.cpp template file used by Visual Studio to create new projects.

Inside format strings, whitespace characters in scanf match any amount of whitespace (including none) in the input. The function skips leading whitespace for most specifiers, except %c.

int main() {
    int x, y;
    float f1, f2;
    scanf("%d%d%f%f", &x, &y, &f1, &f2);
    printf("%d %d %.2f %.2f\n", x, y, f1, f2);
    return 0;
}

2.1 Matching Input Correctly

scanf stops reading a field when encountering a character that cannot belong to the current conversion. For instance, with input -13.45e12#, %d captures 13 (sign consumed, stops at .). A subsequent %f consumes .45e12, stopping at #. Floating-point precision limits can cause rounding artifacts.

Literal characters in the format string (like commas) must be present exactly in the input; otherwise, matching fails and subsequent variables remain uninitialized.

int main() {
    int a, b;
    // Input expected: 22 , 3
    scanf("%d , %d", &a, &b);
    printf("a=%d b=%d\n", a, b);
    return 0;
}

2.2 Understanding the Return Value

scanf returns the number of successfully matched and assigned items. It returns 0 if the first item fails to match. If end-of-file or a read error occurs before any conversion, it returns EOF (typically -1). Press Ctrl+Z (Windows) or Ctrl+D (Unix) followed by Enter to signal EOF.

int main() {
    int age, count;
    float weight;
    int matched = scanf("%d %d %f", &age, &count, &weight);
    printf("Matched: %d\n", matched);
    return 0;
}

2.3 Key Format Specifiers

  • %c : character (reads the next character, including whitespace)
  • %d : integer
  • %f : float
  • %lf : double
  • %Lf : long double
  • %s : word (stops at whitespace; appends null terminator; unsafe without length limit)
  • %[set] : scanset (e.g., %[0-9] reads only digits)

To skip leading whitespace for %c, place a space before the specifier: scanf(" %c", &ch);

%s reads a single word and is inherently unsafe because it can overflow the destination array. To protect against buffer overflows, specify a maximum field width: %9s reads up to 9 characters and automatically appends the null terminator.

#include <stdio.h>
int main() {
    char name[10];
    printf("Enter name: ");
    scanf("%9s", name); // array decays to pointer
    printf("Hello, %s\n", name);
    return 0;
}

3. Assignment Suppression

When parsing variable-format input (e.g., dates with different separators), use the assignment suppression character *. Place * immediately after the % sign; the matched input is discarded and not assigned to any variable.

int main() {
    int yr, mo, dy;
    // Input can be 2025/04/08 or 2025-04-08
    scanf("%d%*c%d%*c%d", &yr, &mo, &dy);
    printf("%04d-%02d-%02d\n", yr, mo, dy);
    return 0;
}

4. Control Flow: Branching with if/else

In C, an expression evaluating to zero is false; any non-zero value (including negative numbers) is true.

#include <stdio.h>
int main() {
    if (-5) {
        printf("Non-zero, so this executes.\n");
    }
    return 0;
}

Nested if-else and else-if Chaining

A typical age classification can be written with nested blocks or a flattened else if ladder.

int main() {
    int age;
    scanf("%d", &age);

    if (age < 18)
        printf("Adolescent\n");
    else if (age <= 44)
        printf("Young Adult\n");
    else if (age <= 59)
        printf("Middle-aged\n");
    else if (age <= 89)
        printf("Senior\n");
    else
        printf("Longevity\n");

    return 0;
}

Statement Blocks and the Dangling else

Without braces {}, if and else govern only the immediately following statement. Always use braces for clarity, especially when nesting. An else always binds to the nearest unmatched if in the same block, regardless of indentation.

This code prints nothing because the else pairs with the inner if(b==2), and the outer if(a==1) never enters its body.

#include <stdio.h>
int main() {
    int a = 0, b = 2;
    if (a == 1)
        if (b == 2)
            printf("Alpha\n");
        else
            printf("Beta\n");
    return 0;
}

Proper use of braces eliminates ambiguity and ensures intended logic.

int main() {
    int a = 0, b = 2;
    if (a == 1) {
        if (b == 2)
            printf("Alpha\n");
    } else {
        printf("Beta\n");
    }
    return 0;
}

Related Articles

Understanding Strong and Weak References in Java

Strong References Strong reference are the most prevalent type of object referencing in Java. When an object has a strong reference pointing to it, the garbage collector will not reclaim its memory. F...

Comprehensive Guide to SSTI Explained with Payload Bypass Techniques

Introduction Server-Side Template Injection (SSTI) is a vulnerability in web applications where user input is improper handled within the template engine and executed on the server. This exploit can r...

Implement Image Upload Functionality for Django Integrated TinyMCE Editor

Django’s Admin panel is highly user-friendly, and pairing it with TinyMCE, an effective rich text editor, simplifies content management significantly. Combining the two is particular useful for bloggi...

Leave a Comment

Anonymous

◎Feel free to join the discussion and share your thoughts.