Input and Output

Input and output are like a conversation between you and the computer — printf is the computer talking to you, scanf is you talking to the computer. Get the format right, or you'll be talking past each other.

printf Formatted Output

printf stands for "print formatted." Its first argument is a format string, followed by the values to output.

Basic Format Specifiers

Specifier Purpose Example Output
%d Decimal integer printf("%d", 42) 42
%f Floating-point printf("%f", 3.14) 3.140000
%c Single character printf("%c", 'A') A
%s String printf("%s", "hi") hi
%x Hexadecimal printf("%x", 255) ff
%o Octal printf("%o", 8) 10
%p Pointer address printf("%p", &a) Address value
%% Literal percent sign printf("100%%") 100%
C
#include <stdio.h>

int main(void) {
    int age = 25;
    float height = 175.5f;
    char grade = 'A';
    printf("Age: %d, Height: %.1f, Grade: %c\n", age, height, grade);
    return 0;
}
TEXT
Age: 25, Height: 175.5, Grade: A

Width and Alignment

You can insert numbers between % and the format specifier to control output width:

C
#include <stdio.h>

int main(void) {
    int num = 42;
    printf("[%5d]\n", num);
    printf("[%-5d]\n", num);
    printf("[%05d]\n", num);
    printf("[%+5d]\n", num);
    return 0;
}
TEXT
[   42]
[42   ]
[00042]
[  +42]

Floating-Point Precision

C
#include <stdio.h>

int main(void) {
    double pi = 3.14159265358979;
    printf("Default:  %f\n", pi);
    printf("2 places: %.2f\n", pi);
    printf("6 places: %.6f\n", pi);
    printf("8.2:      %8.2f\n", pi);
    return 0;
}
TEXT
Default:  3.141593
2 places: 3.14
6 places: 3.141593
8.2:          3.14
💡 Tip: %f defaults to 6 decimal places. Use %.0f to hide the decimal portion entirely.

scanf Reading Input

scanf stands for "scan formatted." It reads data from standard input according to the format string and stores it in variables.

Basic Usage

C
#include <stdio.h>

int main(void) {
    int age;
    float score;
    printf("Enter your age: ");
    scanf("%d", &age);
    printf("Enter your score: ");
    scanf("%f", &score);
    printf("Age: %d, Score: %.1f\n", age, score);
    return 0;
}
TEXT
Enter your age: 20
Enter your score: 92.5
Age: 20, Score: 92.5
⚠️ Note: scanf's variable arguments must be preceded by & (the address-of operator), telling scanf "store the value at this address." Forgetting & is the most common beginner mistake — the program won't error out but will crash.

Reading Multiple Values

C
#include <stdio.h>

int main(void) {
    int a, b, c;
    printf("Enter three integers (separated by spaces): ");
    scanf("%d %d %d", &a, &b, &c);
    printf("You entered: %d, %d, %d\n", a, b, c);
    return 0;
}
TEXT
Enter three integers (separated by spaces): 10 20 30
You entered: 10, 20, 30

By default, scanf uses whitespace (spaces, newlines, tabs) to separate different values.

Reading Characters and Strings

C
#include <stdio.h>

int main(void) {
    char ch;
    char name[20];
    printf("Enter a character: ");
    scanf(" %c", &ch);
    printf("Enter your name (no spaces): ");
    scanf("%s", name);
    printf("Character: %c, Name: %s\n", ch, name);
    return 0;
}
⚠️ Note: Adding a space before %c (" %c") skips whitespace characters, otherwise it will read the leftover newline from previous input. %s reads a string but stops at whitespace. name is an array name, which is already an address, so no & is needed.

scanf's Return Value

scanf returns the number of successfully read variables. This feature can be used to validate input:

C
#include <stdio.h>

int main(void) {
    int num;
    printf("Enter an integer: ");
    int result = scanf("%d", &num);
    if (result == 1) {
        printf("Successfully read: %d\n", num);
    } else {
        printf("Invalid input!\n");
    }
    return 0;
}
TEXT
Enter an integer: abc
Invalid input!

getchar and putchar

getchar() reads a single character from the keyboard, and putchar() outputs a single character to the screen. They're simpler and more efficient than scanf("%c") and printf("%c").

C
#include <stdio.h>

int main(void) {
    char ch;
    printf("Enter a character: ");
    ch = getchar();
    printf("You entered: ");
    putchar(ch);
    putchar('\n');
    return 0;
}
TEXT
Enter a character: X
You entered: X

Reading an Entire Line

getchar() combined with a loop can read an entire line until a newline is encountered:

C
#include <stdio.h>

int main(void) {
    char ch;
    printf("Enter a line of text: ");
    while ((ch = getchar()) != '\n') {
        putchar(ch);
    }
    putchar('\n');
    return 0;
}
TEXT
Enter a line of text: Hello World!
Hello World!
💡 Tip: while ((ch = getchar()) != '\n') is a classic idiom: first read a character into ch, then check if it's a newline. Note that the outer parentheses around the assignment are mandatory.

Buffer Issues

C's standard input uses line buffering: the entire line of data is only delivered to the buffer for the program to read after the user presses Enter. This can cause some confusing problems.

Problem: scanf %c Reads a Leftover Newline

C
#include <stdio.h>

int main(void) {
    int num;
    char ch;
    printf("Enter an integer: ");
    scanf("%d", &num);
    printf("Enter a character: ");
    scanf("%c", &ch);
    printf("Integer=%d, Character=%d\n", num, ch);
    return 0;
}
TEXT
Enter an integer: 42
Enter a character: Integer=42, Character=10

After typing 42 and pressing Enter, the buffer contains 42\n. scanf("%d") reads 42, and scanf("%c") immediately reads that leftover \n (ASCII code 10), without waiting for you to type a character.

Solutions

Solution 1: Add a space before %c (recommended)

C
scanf(" %c", &ch);

The space skips all whitespace characters (including newlines, spaces, and tabs).

Solution 2: Use getchar() to absorb the leftover

C
scanf("%d", &num);
getchar();
scanf("%c", &ch);

Solution 3: Clear the input buffer

C
int c;
while ((c = getchar()) != '\n' && c != EOF) {}
⚠️ Note: Don't use fflush(stdin) to clear the input buffer — it's undefined behavior in standard C. Some compilers support it, but it's not portable.

Example

Write a program that reads both an integer and a character, properly handling buffer leftovers:

C
#include <stdio.h>

int main(void) {
    int age;
    char gender;
    printf("Enter your age: ");
    scanf("%d", &age);
    printf("Enter your gender (M/F): ");
    scanf(" %c", &gender);
    printf("Age: %d, Gender: %c\n", age, gender);
    return 0;
}
▶ Try it Yourself
TEXT
Enter your age: 25
Enter your gender (M/F): M
Age: 25, Gender: M

Example

Use getchar() to read character by character and count the number of letters and digits in a line:

C
#include <stdio.h>

int main(void) {
    char ch;
    int letters = 0;
    int digits = 0;
    printf("Enter a line of text: ");
    while ((ch = getchar()) != '\n') {
        if (ch >= 'A' && ch <= 'Z' || ch >= 'a' && ch <= 'z') {
            letters++;
        } else if (ch >= '0' && ch <= '9') {
            digits++;
        }
    }
    printf("Letters: %d, Digits: %d\n", letters, digits);
    return 0;
}
▶ Try it Yourself
TEXT
Enter a line of text: Hello 2024!
Letters: 5, Digits: 4

puts and fputs

puts() outputs a string and automatically appends a newline. It's simpler than printf and ideal for plain text output:

C
#include <stdio.h>

int main(void) {
    puts("Hello, World!");
    puts("Auto newline, no need for \\n");
    return 0;
}
TEXT
Hello, World!
Auto newline, no need for \n
💡 Tip: puts() is more efficient than printf("%s\n", ...) because it doesn't need to parse a format string. When you don't need formatting, prefer puts.

❓ FAQ

Q Why do scanf variables need & in front?
A scanf needs to know where to store the value, and & takes the variable's address. Only array names don't need it, because an array name is already the address of its first element.
Q scanf("%c") skipped my input — what happened?
A There's a leftover newline in the buffer from a previous input. Add a space before %c: scanf(" %c", &ch) to skip whitespace.
Q Can printf and scanf format specifiers be uppercase?
A Some can. %d lowercase corresponds to int; uppercase %D is non-standard. But %x prints lowercase hex (abcdef) while %X prints uppercase (ABCDEF) — this is valid.
Q How do I safely read a string with spaces?
A scanf("%s") stops at whitespace. Use fgets(name, sizeof(name), stdin) to read an entire line — it supports spaces and is safer.

📖 Summary

📝 Exercises

  1. Write a program that reads a circle's radius and outputs its area and circumference using printf's %.2f format.
  2. Write a program that uses getchar() to read a line of input and counts how many uppercase and lowercase letters it contains.
  3. Write a program that reads an integer and outputs it in decimal (%d), hexadecimal (%x), and octal (%o) formats.
100%

🙏 帮我们做得更好

我们是刚上线的编程教程站,几个人的小团队,精力有限。页面虽经检查,难免还有疏漏——链接失效、排版错乱、内容有误、语言生硬……

如果您发现了,麻烦告诉我们,我们会在收到反馈后第一时间进行修复,再次感谢您的光临 🙏