C Input/Output - Tricky MCQ

Previous C Input/Output Functions Next

Tricky Questions on Input/Output Functions

1

What is the return value of printf() function?

Correct Answer: B) Number of characters printed (excluding null)

printf() returns the number of characters successfully written to the output stream (excluding the null terminator). On failure, it returns a negative value. This is useful for checking if output was successful and for formatting.

int count = printf("Hello, World!"); // count = 13 (characters in "Hello, World!") int count2 = printf("%d", 12345); // count2 = 5 (digits in 12345)
2

What happens if format specifier doesn't match argument type in printf()?

Correct Answer: C) Undefined behavior (garbage output)

When format specifiers don't match argument types in printf(), it leads to undefined behavior. The compiler may not catch it (especially with variables), and you'll get garbage output. This is because printf() uses varargs and relies on the format string to interpret arguments correctly.

int x = 65; printf("%f", x); // UNDEFINED BEHAVIOR! Will print garbage double d = 3.14; printf("%d", d); // UNDEFINED BEHAVIOR! Will print garbage // Correct: printf("%d", x); // Prints: 65 printf("%f", d); // Prints: 3.140000
3

What is the difference between puts() and printf() for string output?

Correct Answer: A) puts() automatically adds newline, printf() doesn't

puts(str) writes the string str followed by a newline character to stdout. printf("%s", str) only writes the string without automatically adding a newline. puts() is generally faster for simple string output as it doesn't parse format strings.

char str[] = "Hello"; puts(str); // Output: "Hello\n" (with newline) printf("%s", str); // Output: "Hello" (no newline) printf("%s\n", str); // Equivalent to puts(str) // puts() returns non-negative value on success, EOF on error // printf() returns number of characters printed
4

What does scanf() return?

Correct Answer: A) Number of successfully read items

scanf() returns the number of input items successfully matched and assigned. This is useful for error checking. If input fails before any assignment, it returns EOF. If there's a matching failure, it returns the number of items successfully read before the failure.

int a, b, result; result = scanf("%d %d", &a, &b); // Input: "10 20" → result = 2 (both read) // Input: "10 abc" → result = 1 (only first read) // Input: "abc" → result = 0 (no matches) // Input failure (Ctrl+D) → result = EOF // Always check return value! if (scanf("%d", &a) != 1) { printf("Invalid input!\n"); }
5

Why is gets() dangerous and deprecated?

Correct Answer: A) No bounds checking (buffer overflow risk)

gets() reads input until newline or EOF, with no way to limit input size. If input exceeds buffer size, it causes buffer overflow (writing beyond allocated memory), leading to crashes or security vulnerabilities. It was removed from C11. Use fgets() instead.

// DANGEROUS: char buffer[10]; gets(buffer); // If input > 9 chars + null → BUFFER OVERFLOW! // SAFE alternative: char buffer[10]; fgets(buffer, sizeof(buffer), stdin); // Reads at most 9 chars + null // fgets includes newline in buffer if there's room // gets removes newline, fgets keeps it
6

What is the difference between %i and %d in printf/scanf?

Correct Answer: A) No difference in printf(), but in scanf(): %i reads octal/hex/decimal

In printf(), %i and %d are identical - both print signed decimal integers. In scanf(), %d reads only decimal numbers, while %i interprets input based on prefix: decimal (no prefix), octal (0 prefix), or hexadecimal (0x or 0X prefix).

int num; // scanf with %d: scanf("%d", &num); // Input "010" → num = 10 (decimal) // Input "0x10" → fails (not decimal) // scanf with %i: scanf("%i", &num); // Input "010" → num = 8 (octal: 010 = 8 decimal) // Input "0x10" → num = 16 (hex: 0x10 = 16 decimal) // Input "10" → num = 10 (decimal) // printf with both: printf("%d", num); // Always prints decimal printf("%i", num); // Always prints decimal (same as %d)
7

What does %n format specifier do in printf()?

Correct Answer: B) Stores count of characters printed so far

The %n format specifier is unique - it doesn't print anything. Instead, it stores the number of characters that have been printed by printf() up to that point into an int pointer argument. Useful for formatting or progress tracking.

int count1, count2; printf("Hello%n World%n!\n", &count1, &count2); // Output: "Hello World!" // count1 = 5 (characters in "Hello") // count2 = 11 (characters in "Hello World") printf("Count1: %d, Count2: %d\n", count1, count2); // Output: "Count1: 5, Count2: 11" // Security note: %n can be dangerous in format string attacks // as it allows writing to memory
8

How to flush output buffer in C?

Correct Answer: C) Both A and B are correct

Standard output is typically line-buffered when connected to terminal. fflush(stdout) explicitly flushes the buffer. Printing a newline (\n) also flushes the buffer when output is line-buffered. For immediate output without newline, use fflush(stdout).

printf("Hello"); // May not appear immediately (buffered) fflush(stdout); // Forces output to appear now printf("Hello\n"); // Newline flushes line-buffered output // Set to unbuffered for immediate output: setbuf(stdout, NULL); // No buffering printf("Hello"); // Appears immediately // For file output, buffering is different FILE *fp = fopen("file.txt", "w"); setvbuf(fp, NULL, _IOFBF, 1024); // Full buffering, 1KB buffer
9

What happens if you don't use & with variables in scanf()?

Correct Answer: C) Undefined behavior (writes to wrong location)

scanf() needs memory addresses (& operator) to store input values. Without &, it treats the variable's value as an address, leading to writing input to a random memory location → undefined behavior (crash, corruption, etc.). Exception: arrays (array name decays to pointer).

int x; scanf("%d", x); // WRONG! Uses value of x as address // UNDEFINED BEHAVIOR - likely crash scanf("%d", &x); // CORRECT! Passes address of x char str[100]; scanf("%s", str); // CORRECT! str decays to pointer // Equivalent to: scanf("%s", &str[0]); int *ptr = &x; scanf("%d", ptr); // CORRECT! ptr already holds address
10

What is the difference between fprintf() and printf()?

Correct Answer: A) printf() is for stdout, fprintf() for any FILE*

printf() always writes to stdout. fprintf() writes to any FILE* stream (files, stderr, stdout, etc.). printf(format, ...) is equivalent to fprintf(stdout, format, ...). Use fprintf(stderr, ...) for error messages.

printf("Hello\n"); // Writes to stdout // Equivalent to: fprintf(stdout, "Hello\n"); // Write to file: FILE *fp = fopen("output.txt", "w"); fprintf(fp, "Hello file!\n"); // Write to stderr (unbuffered by default): fprintf(stderr, "Error message!\n"); // sprintf writes to string buffer: char buffer[100]; sprintf(buffer, "Value: %d", 42); // Writes to buffer
11

What does the * modifier do in printf format specifiers?

Correct Answer: B) Dynamic width/precision from argument

In printf() format strings, * allows dynamic width/precision from an argument instead of hardcoded values. The argument must be an int. Useful when width/precision isn't known at compile time.

int width = 10, precision = 4; double value = 3.14159265; printf("%*.*f\n", width, precision, value); // Equivalent to: printf("%10.4f\n", value); // Output: " 3.1416" (10 width, 4 decimal places) // Negative width means left-justified: width = -10; printf("%*.*f\n", width, precision, value); // Output: "3.1416 " (left-justified) // For integers: printf("%0*d\n", 5, 42); // Output: "00042" (width 5, zero-padded)
12

What's wrong with: scanf("%s", &name); where name is char array?

Correct Answer: C) Works but gives warning

For arrays, name decays to &name[0] (pointer to first element). &name gives the address of the array itself (same value but different type: char(*)[100] vs char*). It usually works but gives a type mismatch warning. Best practice: use name without &.

char name[100]; scanf("%s", name); // CORRECT and clean scanf("%s", &name[0]); // Also correct, explicit scanf("%s", &name); // Works but type mismatch warning // The values are numerically same but types differ: // name → char* (pointer to char) // &name[0] → char* (pointer to char) // &name → char(*)[100] (pointer to array of 100 chars) // For non-arrays (like int), MUST use &: int x; scanf("%d", &x); // CORRECT scanf("%d", x); // WRONG - UB!
13

What is the purpose of fpurge()/fflush() on input streams?

Correct Answer: A) Discard unread input in buffer

fflush() on output streams writes buffered data. On input streams, behavior is implementation-defined. fpurge() (BSD) or __fpurge() (Glibc) discards unread input. Standard portable way: read and discard with a loop. Used to clear leftover input (like newline after scanf()).

// Problem: scanf leaves newline in buffer int age; char name[100]; printf("Enter age: "); scanf("%d", &age); // Reads number, leaves '\n' printf("Enter name: "); fgets(name, 100, stdin); // Reads leftover '\n' immediately! // Solution 1: Consume leftover characters int c; while ((c = getchar()) != '\n' && c != EOF); // Discard line // Solution 2: Use fpurge (non-portable) // fpurge(stdin); // BSD, not standard // Better: Read entire lines with fgets() // then parse with sscanf()
14

What is the difference between %f, %e, and %g for floating point?

Correct Answer: A) %f: decimal, %e: scientific, %g: shortest representation

%f prints in decimal notation (e.g., 123.456000). %e prints in scientific notation (e.g., 1.234560e+02). %g uses either %f or %e, whichever is more compact (removes trailing zeros). %a (C99) prints hexadecimal floating point.

double x = 123.456; printf("%f\n", x); // 123.456000 (decimal) printf("%e\n", x); // 1.234560e+02 (scientific) printf("%g\n", x); // 123.456 (compact) double y = 0.0000123456; printf("%f\n", y); // 0.000012 (loses precision) printf("%e\n", y); // 1.234560e-05 (scientific) printf("%g\n", y); // 1.23456e-05 (compact) // With precision: printf("%.2f\n", x); // 123.46 printf("%.2e\n", x); // 1.23e+02 printf("%.2g\n", x); // 1.2e+02 (2 significant digits)
15

How to read/write binary data in C?

Correct Answer: D) Both A and B

For binary I/O: fread() and fwrite() (standard library) read/write raw bytes. read() and write() (POSIX system calls) also work. Open files in binary mode ("rb", "wb") to avoid newline translation. Text functions like fprintf() convert data to text representation.

// Write binary data struct Record { int id; double value; char name[50]; } rec = {1, 3.14, "Test"}; FILE *fp = fopen("data.bin", "wb"); // Binary mode if (fp) { fwrite(&rec, sizeof(rec), 1, fp); fclose(fp); } // Read binary data fp = fopen("data.bin", "rb"); // Binary mode if (fp) { struct Record rec2; fread(&rec2, sizeof(rec2), 1, fp); fclose(fp); } // System call approach (POSIX) int fd = open("data.bin", O_RDWR | O_CREAT, 0644); write(fd, &rec, sizeof(rec)); read(fd, &rec2, sizeof(rec2)); close(fd);
Previous C Input/Output Functions Next