Input and Output in C
Input and Output in C
C has no built-in print statement. printf and scanf are ordinary functions living in the standard library, which is exactly why you must write #include <stdio.h> to use them. That header does not contain the functions themselves. It contains their declarations, telling the compiler what arguments they expect and what they return. The actual machine code is joined in later by the linker.
Understanding that these are just functions explains most of their odd behaviour.
How printf actually works
printf takes a format string followed by zero or more values. It walks the format string character by character, copying ordinary characters straight to the screen. When it hits a %, it stops copying, reads the specifier that follows, and pulls the next argument off the list to format it.
That last part is important: printf does not check that you gave it the right type. It trusts the format string completely. If the string says %d and you pass a double, printf will read those bytes as if they were an integer and print nonsense.
#include <stdio.h>
int main(void)
{
int roll = 17;
float marks = 82.5f;
char grade = 'A';
double ratio = 0.6666666666;
printf("Roll : %d\n", roll);
printf("Marks : %f\n", marks);
printf("Marks : %.1f\n", marks);
printf("Grade : %c\n", grade);
printf("Ratio : %.4lf\n", ratio);
printf("Name : %s\n", "Ananya");
printf("Hex : %x Octal: %o\n", 255, 255);
return 0;
}
The specifiers you will actually use
| Specifier | Prints | Example output |
|---|---|---|
%d |
Signed integer | 42 |
%u |
Unsigned integer | 42 |
%f |
float or double | 3.140000 |
%.2f |
Rounded to 2 decimals | 3.14 |
%c |
Single character | A |
%s |
String, i.e. char array | Ananya |
%x |
Integer in hexadecimal | ff |
%o |
Integer in octal | 377 |
%zu |
Result of sizeof | 4 |
%% |
A literal percent sign | % |
Two notes that clear up common confusion. In printf, %f handles both float and double, because a float argument is automatically widened to double when passed. In scanf this is not true and the distinction between %f and %lf genuinely matters. Second, %.2f rounds for display; it does not change the stored value.
Width and alignment
A number between the % and the specifier sets a minimum field width, which is how you line up columns in a table.
#include <stdio.h>
int main(void)
{
printf("%-10s %8s %6s\n", "Subject", "Marks", "Grade");
printf("%-10s %8d %6c\n", "Maths", 91, 'A');
printf("%-10s %8d %6c\n", "Physics", 78, 'B');
printf("%-10s %8d %6c\n", "Chem", 65, 'C');
printf("\n%08.3f\n", 3.14159);
return 0;
}
%-10s left-aligns a string in a field ten characters wide. Without the minus sign the value is right-aligned, which is what you usually want for numbers. %08.3f pads with zeros to a total width of eight, with three decimal places.
Escape sequences
Some characters cannot be typed directly inside a string literal, so C uses a backslash to escape them.
| Sequence | Meaning |
|---|---|
\n |
Newline |
\t |
Horizontal tab |
\\ |
A single backslash |
\" |
A double quote inside a string |
\' |
A single quote inside a char constant |
\0 |
The null character, value zero |
\r |
Carriage return |
\n matters more than it looks. Output is usually line buffered, meaning the text sits in a buffer until a newline arrives. If your program prints without a newline and then crashes, that text may never appear, making the crash look like it happened earlier than it did.
printf("C:\new\table\n"); does not print a path. \n and \t are escape sequences, so you get a newline and a tab. Write printf("C:\\new\\table\\n"); when you want literal backslashes.
Reading input with scanf
scanf is the mirror image of printf, and it is where most beginner frustration lives. Here is the basic shape.
#include <stdio.h>
int main(void)
{
int age;
printf("Enter your age: ");
scanf("%d", &age);
printf("You are %d\n", age);
return 0;
}
The ampersand in &age is not decoration. C passes arguments by value, so scanf receives copies. A copy is useless for storing a result. &age means "the address of age", which gives scanf somewhere real to write. Forgetting the ampersand is the single most common C mistake in first-year labs, and it typically compiles with only a warning before crashing at run time.
The one exception: an array name already behaves as an address, so reading a string uses no ampersand.
char name[50];
scanf("%49s", name);
The 49 caps how many characters are read, leaving room for the terminating null. Plain %s with no limit will happily write past the end of your array and corrupt memory. Also note that %s stops at the first space, so "Adnan Hassan" reads as "Adnan" and the rest stays waiting in the buffer.
The scanf traps
Trap 1: leftover newline before %c. After scanf("%d", &n); the Enter key you pressed is still sitting in the input buffer. A following scanf("%c", &ch); immediately consumes that newline instead of waiting for you. The fix is a space in the format string, which tells scanf to skip whitespace first.
scanf("%d", &n);
scanf(" %c", &ch);
Trap 2: %f versus %lf. In scanf you must use %f for a float and %lf for a double. Getting this wrong writes the wrong number of bytes into your variable and corrupts whatever sits next to it.
Trap 3: ignoring the return value. scanf returns how many items it successfully read. If the user types "hello" when you asked for %d, nothing is read, your variable keeps its old value, and the bad text stays in the buffer, so the next scanf fails too.
if (scanf("%d", &n) != 1) {
printf("That was not a number.\n");
return 1;
}
Most online judges and the Run button on this site feed no keyboard input, so a program waiting on scanf simply hangs. While you are learning a new concept, assign values directly in the code. Bring scanf back once the logic is already correct.
Common mistakes
- Missing
&inscanf.scanf("%d", n);compiles with a warning and then crashes. Writescanf("%d", &n); - Mismatched specifier and variable.
scanf("%d", &price);wherepriceis afloatwrites four bytes of integer into a float. Match them exactly. - Using
%cright after%d. The stray newline gets consumed. Use" %c"with a leading space. - Unbounded
%s. Always give a width, such as%49sfor achar[50]. - Expecting
%sto read a full line. It stops at whitespace. Usefgetswhen you need an entire line including spaces. - Assuming
%.2fchanges the value. It only changes the display. The variable still holds the full precision.
Formatted output is a skill you will use in every program you ever write in this language, and reading input carefully is what separates a program that works from one that works only when the user cooperates. Put both to work on the Practice page.