What is scanf Assignment Suppression Tutorial-Online Embedded C Programming Classes

Need Help or More Information?

Questions about this free C programming course, embedded C training or career guidance? Get in touch.

Input-Output in C · Free Embedded C Course

scanf Assignment Suppression Tutorial

Learn the %*d trick: let scanf read a value from the input and quietly throw it away. Every program below was compiled and run, so the outputs you see are real.

5
Tested programs
5
Quiz questions
12
Minutes to read

What You Will Learn

By the end of this lecture you can:

  • Explain what scanf assignment suppression is and why a single * changes the meaning of a conversion.
  • Predict exactly how many values scanf stores, and read its return value correctly.
  • Skip unwanted fields in dates, log lines and comma-separated records.
  • Clean leftover characters from the input line with %*[^\n] and %*c.
  • Spot the classic bug where an argument is passed for a skipped field.

Prerequisites

You should already know how printf and scanf work at a basic level, what a conversion specifier such as %d or %s is, and why scanf needs the address of a variable (the & operator). If those ideas are new, go back one lecture in this free embedded systems course, then come here. Compiler used for all examples: GCC with -std=c17 -Wall -Wextra.

What Is scanf Assignment Suppression?

Normally every conversion in a scanf format string does two jobs: it reads some characters from the input, converts them, and then stores the result through the next pointer argument. scanf assignment suppression cancels the second job. You write a * right after the %, and scanf still reads and checks the characters, but it does not store anything and it does not use up a pointer argument.

Think of it as reading a form where some boxes are irrelevant to you. You have to move your eyes past them to reach the box you care about, but you do not copy their content anywhere. That is all %*d means: “there is an integer here, consume it, forget it.”

The Syntax at a Glance

SpecificationInput it consumesStored in a variable?Needs a pointer argument?
%dan integerYesYes (int *)
%*dan integerNo, discardedNo
%sone word (up to whitespace)YesYes (char *)
%*sone wordNo, discardedNo
%cexactly one characterYesYes
%*cexactly one characterNo, discardedNo
%*[^\n]everything up to the end of the lineNo, discardedNo

Following One Input Through the Format

Suppose the user types 25 30 35 and your format is %d %*d %d. The diagram shows which input token meets which specification. Bright boxes are stored; dim boxes are skipped.

scanf(“%d %*d %d”, &first, &last) reading: 25 30 35
Input tokens : 253035
Specifications : %d%*d%d
What happens : store in firstread and dropstore in last
Return value : 2 values stored (the skipped one is not counted)

Notice the third row. scanf returns the number of values it actually assigned. A suppressed conversion is never counted, even though it consumed input successfully. This detail matters every time you validate input with if (scanf(...) == N).

Example 1: Skip the Middle Number

This is the smallest useful program. It reads three numbers but keeps only the first and the last, and it prints the return value so you can watch the counting rule in action.

File: s1_basic.c

#include <stdio.h>

int main(void)
{
    int first = 0, last = 0;
    int stored;

    printf("Enter three numbers: ");
    stored = scanf("%d %*d %d", &first, &last);

    printf("scanf stored %d value(s)\n", stored);
    printf("first = %d, last = %d\n", first, last);
    return 0;
}

Build and run:

gcc -std=c17 -Wall -Wextra -o s1_basic s1_basic.c
./s1_basic

Expected output when you type three numbers:

Enter three numbers: 25 30 35
scanf stored 2 value(s)
first = 25, last = 35

Now run it again but type only two numbers. The second conversion that stores (%d for last) finds nothing, so scanf stops early:

Enter three numbers: 7 8
scanf stored 1 value(s)
first = 7, last = 0

Read that carefully. With input 7 8 the first %d stored 7, %*d swallowed 8, and the last %d hit the end of the line and failed. The return value is 1, and last kept the 0 we gave it at declaration. This is why we always initialise variables that scanf might not reach.

The Classic Bug: One Pointer Too Many

A very common mistake is to count the skipped field when listing arguments. Beginners write three variables for a format that only has two storing conversions. Here is that bug on purpose:

#include <stdio.h>

int main(void)
{
    int x = 0, y = 0, z = -1;          /* -1 marks "never written" */

    scanf("%d %*d %d", &x, &y, &z);    /* BUG: only two conversions store */
    printf("x=%d y=%d z=%d\n", x, y, z);
    return 0;
}

GCC notices it right away if you compile with warnings on:

s2_sentinel.c:7:11: warning: too many arguments for format [-Wformat-extra-args]

Run it with 25 30 35:

x=25 y=35 z=-1

Read the output closely

The variable z stayed at -1. The extra pointer was never used because the format only has two storing conversions. If z had been left uninitialised, you would print a random leftover number from the stack and wonder where it came from. The rule: the number of pointer arguments must equal the number of conversions without a *. Always compile with -Wall.

Example 2: Pull the Month and Year from a Date

Suppose a sensor logger stores dates as dd-mm-yyyy and your report only needs the month and year. A literal - in the format must match the same character in the input. Combined with suppression, the format becomes very compact.

#include <stdio.h>

int main(void)
{
    int month = 0, year = 0;

    printf("Enter date (dd-mm-yyyy): ");
    if (scanf("%*d-%d-%d", &month, &year) == 2)
        printf("Month = %d, Year = %d\n", month, year);
    else
        printf("Bad format\n");
    return 0;
}
Enter date (dd-mm-yyyy): 22-10-2026
Month = 10, Year = 2026

Because we compare the return value with 2, bad input is caught. Typing the same date with slashes makes the literal - fail to match:

Enter date (dd-mm-yyyy): 22/10/2026
Bad format

Example 3: Read One Field from a Log Line

Embedded devices often print status lines such as WARN disk 85. Maybe you only need the number at the end. Skip the two words with %*s and capture the integer:

#include <stdio.h>

int main(void)
{
    int percent = 0;

    printf("Log line: ");
    if (scanf("%*s %*s %d", &percent) == 1)
        printf("Usage: %d%%\n", percent);
    return 0;
}
Log line: WARN disk 85
Usage: 85%

Two details to observe. First, %*s stops at whitespace, so each one skips exactly one word. Second, %% inside printf prints a literal percent sign. This pattern scales: to read the 5th word of a line you write four %*s and one real conversion.

Example 4: Skip Text up to a Comma

The scan set %[^,] means “read any characters except a comma”. Add the * and it skips a whole text field of any length. This handles records like Asha,27 where the name length varies:

#include <stdio.h>

int main(void)
{
    int age = 0;

    printf("Record (name,age): ");
    if (scanf("%*[^,],%d", &age) == 1)
        printf("Age = %d\n", age);
    return 0;
}
Record (name,age): Asha,27
Age = 27

Example 5: Clean the Input Line with scanf Suppression

This is the use that saves beginners the most pain. After scanf("%d", ...) the Enter key’s newline is still waiting in the input. The next %c reads that newline instead of the letter you typed. Two suppressed conversions remove the leftovers:

#include <stdio.h>

int main(void)
{
    int num = 0;
    char ch = '?';

    printf("Number: ");
    scanf("%d", &num);
    scanf("%*[^\n]");      /* throw away the rest of the line */
    scanf("%*c");          /* throw away the newline itself   */

    printf("Letter: ");
    scanf("%c", &ch);
    printf("num=%d ch=%c\n", num, ch);
    return 0;
}

Type 42 abc, press Enter, then type a letter:

Number: 42 abc
Letter: Z
num=42 ch=Z

The first scanf took 42. The line still contained abc and a newline. %*[^\n] removed everything up to the newline, and %*c removed the newline itself. Only then did %c see the letter.

Why two separate calls?

If the line is already empty, %*[^\n] matches zero characters and fails. When both conversions are in one format string, scanf stops at the failure and never reaches %*c, so the newline stays behind. Two separate calls make the cleanup work in both cases.

How scanf Handles Whitespace While Skipping

Most numeric conversions such as %d and %s first skip leading whitespace. %c and the scan set %[ do not. That includes the suppressed forms, so %*c removes exactly one character, whitespace or not. Compare these two formats on the input xy followed by Enter:

FormatInputWhat gets stored
%*c%cxyx dropped, y stored
%*d %d10 2010 dropped, spaces skipped automatically, 20 stored
%d,%*d,%d10,20,3010 and 30 stored, 20 dropped, return value 2

Common Mistakes with scanf Assignment Suppression

SymptomLikely causeFix
Variable shows a random numberscanf stopped before reaching it and the variable was never initialisedInitialise to a known value and test the return value
Compiler says too many arguments for formatYou passed a pointer for a %* fieldRemove the pointer; only non-suppressed conversions take one
%c reads a newlineNewline from an earlier Enter is still in the inputUse scanf("%*[^\n]") then scanf("%*c"), or a space before %c
Return value is lower than expectedSuppressed fields are not countedCompare against the number of storing conversions only
Literal text in the format never matchesInput uses a different separatorPrint the raw input first and compare character by character

Best Practices

  • Compare scanf‘s return value with the number of storing conversions every time.
  • Initialise every variable that scanf might leave untouched.
  • Use suppression for fields you truly never need. If you might want the value later, store it.
  • For text fields, add a width such as %19s when storing into an array so you never overflow it. Suppressed fields store nothing, so they have no overflow risk.
  • For serious text parsing on embedded targets, read a line with fgets and then use sscanf with the same formats you learned here.

Why this matters on real devices

Firmware tools, serial consoles and test scripts constantly parse short fixed-format lines. Knowing how to skip a field without declaring a throwaway variable keeps parsing code short and avoids unused-variable warnings. The same skill carries over to sscanf when you later read data from a UART buffer in this free embedded C course.

Try It Yourself: Quick Quiz

Predict each answer first, then open the box. All answers were verified by running the code.

Q1. Input 1 2 3 4. What are a and b after scanf("%d %*d %*d %d", &a, &b)?

a = 1 and b = 4. The two middle numbers are read and dropped.

Q2. Input 5 6. What does scanf("%*d %*d") return?

0. Both conversions succeeded, but suppressed conversions are never counted as assignments.

Q3. Input xy. What does ch hold after scanf("%*c%c", &ch)?

The letter y. %*c consumed the x.

Q4. Input 10,20,30 with scanf("%d,%*d,%d", &a, &b). Return value, a, b?

Return value 2, a = 10, b = 30.

Q5. Input 25 30 with scanf("%d %*d %d", &a, &b), both initialised to 0. Return value, a, b?

Return value 1, a = 25, b = 0. The 30 was skipped, then there was nothing left for the last %d.

Interview Questions

What does the asterisk in %*d do?

It suppresses assignment. scanf reads and converts an integer but discards it and does not consume a pointer argument.

Does a suppressed conversion increase the value returned by scanf?

No. The return value counts only successful assignments to arguments.

How is %*d in scanf different from %*d in printf?

In scanf the star means skip. In printf the star means the field width is taken from an int argument, for example printf("%*d", 6, 42).

Why is scanf("%*[^\n]") followed by scanf("%*c") a useful idiom?

It discards the rest of the current line and the newline so the next character read starts a fresh line.

Key Takeaways on scanf Assignment Suppression

Remember these five points

  • A * after % means: read it, check it, do not store it.
  • Suppressed conversions take no pointer argument and are not counted in scanf’s return value.
  • Pointer arguments must match the storing conversions, one for one.
  • %*[^\n] and %*c clean the line after a numeric read.
  • Initialise variables and check the return value, because scanf can stop early.

Assignment suppression is a small feature, but it teaches the real model behind scanf: the format string is a pattern that walks along the input one piece at a time, and each piece either lands in a variable or disappears. Once you see scanf that way, strange behaviours such as leftover newlines or early stops become predictable. In the next lecture of this free embedded systems course we move to single-character input with getchar and putchar, where the same newline puzzle appears again with a different solution.

Frequently Asked Questions

What is scanf assignment suppression in C?

It is the * placed after % in a scanf conversion, such as %*d. scanf reads the input but does not store it in any variable.

Does %*d need an argument?

No. A suppressed conversion takes no pointer argument. Passing one is a bug that GCC reports with -Wformat-extra-args.

Is the skipped value counted in scanf’s return value?

No. scanf returns only the number of successful assignments.

Can I suppress a string field of unknown length?

Yes. %*s skips one word and %*[^,] skips everything up to a comma. Nothing is stored, so there is no buffer to overflow.

How do I discard the rest of a line after scanf?

Call scanf("%*[^\n]") and then scanf("%*c"). Another common way is a loop with getchar, covered in the next lecture.

Does assignment suppression work with sscanf and fscanf?

Yes. The whole scanf family shares the same format rules.

Is this lecture part of a free embedded C course?

Yes. It belongs to the free embedded systems course on EmbeddedPathashala that builds the C foundation needed before Linux kernel and device driver work.

Keep Going with the Free Embedded C Course

Next you will learn character-level input with getchar and putchar. Everything on EmbeddedPathashala is free, from C basics to Linux kernel and device drivers.

Need Help or More Information?

Questions about this free C programming course, embedded C training or career guidance? Get in touch.

2 Comments

Leave a Reply

Your email address will not be published. Required fields are marked *