Company Corner

C Programs Using Command Line Arguments: Worked Examples

Worked C programs that read input via argc and argv: covers atoi, strtol, and common off-by-one bugs students hit in TCS coding rounds.

By FACE Prep Team 6 min read
c-programming command-line-arguments tcs-coding argc-argv placement-prep

Command line arguments let a C program receive input at launch without waiting for scanf or fgets inside the running process. TCS coding rounds test this pattern regularly because it isolates the logic from I/O boilerplate.

How Command Line Arguments Work in C

The standard entry point signature is:

int main(int argc, char *argv[])
  • argc (argument count) holds the total number of strings passed on the command line, including the program name itself. It is always at least 1.
  • argv (argument vector) is an array of char * pointers. argv[0] is the program name. argv[1] through argv[argc - 1] are the user-supplied arguments.
  • argv[argc] is guaranteed to be NULL by the C standard. Some programs use this as a loop sentinel instead of checking argc explicitly.

A quick mental model: if you compile a file called sum.c and run ./sum 10 20 30, then argc is 4, argv[0] is "./sum", argv[1] is "10", argv[2] is "20", argv[3] is "30", and argv[4] is NULL.

Two equivalent signatures exist in practice:

int main(int argc, char *argv[])   // array notation
int main(int argc, char **argv)    // pointer notation

Both compile identically. The array notation is more common in textbooks and TCS coding examples; the pointer notation appears more often in open-source codebases. Pick whichever your placement prep material uses and stay consistent.

Every element of argv is a string. Even "10" arrives as a two-character null-terminated string, not the integer 10. Converting these strings to numeric types is the next problem.

Converting String Arguments to Integers

atoi — simple but unsafe

atoi(argv[1]) converts the string to an int. It works for well-formed input but has a critical flaw: on invalid input (e.g., "abc"), it returns 0 with no error indicator. If 0 is also a valid input for your program, you cannot tell whether the user passed "0" or garbage.

strtol — the safer alternative

strtol (string-to-long) provides two error-detection mechanisms:

  • It stores a pointer to the first character it could not convert (the endptr parameter). If *endptr is not '\0', the string contained non-numeric trailing characters.
  • It sets errno to ERANGE on overflow or underflow.

The standard safe-parsing pattern:

#include <stdio.h>
#include <stdlib.h>
#include <errno.h>

int main(int argc, char *argv[])
{
    if (argc < 2) {
        printf("Usage: %s <integer>\n", argv[0]);
        return 1;
    }

    char *endptr;
    errno = 0;
    long value = strtol(argv[1], &endptr, 10);

    if (errno != 0) {
        perror("strtol");
        return 1;
    }
    if (*endptr != '\0') {
        printf("Invalid integer: %s\n", argv[1]);
        return 1;
    }

    printf("Parsed value: %ld\n", value);
    return 0;
}

For TCS coding-round problems that use atoi, the programs will work because the automated judge always passes valid numeric strings. But in production code and in interview discussions about error handling, strtol is the expected answer.

Compilation and Execution Pattern

Every example below follows the same three-step cycle. Understanding this cycle matters because TCS coding rounds that use command-line input expect you to visualise execution without an IDE.

  • Step 1: Compile with gcc -o programname programname.c
  • Step 2: Run with ./programname arg1 arg2 ... argN
  • Step 3: The OS splits the command line on whitespace and populates argc and argv before main() executes

If you need to pass an argument that contains a space (e.g., a multi-word filename or string), wrap it in double quotes on the command line: ./program "hello world". The shell treats the quoted portion as a single argv entry rather than splitting it into two.

Worked Examples

Example 1: Print the program name

#include <stdio.h>

int main(int argc, char *argv[])
{
    printf("Program name: %s\n", argv[0]);
    printf("Total arguments (including program name): %d\n", argc);
    return 0;
}
  • Compile: gcc -o nameprint nameprint.c
  • Run: ./nameprint hello world
  • Output:
Program name: ./nameprint
Total arguments (including program name): 3

Re-derivation: "./nameprint" is argv[0], "hello" is argv[1], "world" is argv[2]. Count = 3.

Example 2: Even or odd checker

#include <stdio.h>
#include <stdlib.h>

int main(int argc, char *argv[])
{
    if (argc < 2) {
        printf("Usage: %s <number>\n", argv[0]);
        return 1;
    }

    int number = atoi(argv[1]);

    if (number % 2 == 0)
        printf("%d is even.\n", number);
    else
        printf("%d is odd.\n", number);

    return 0;
}
  • Run: ./evenodd 7

  • Output: 7 is odd.

  • Re-derivation: 7 % 2 = 1 (non-zero), so the else branch prints “7 is odd.”

Example 3: Sum of N integers from the command line

#include <stdio.h>
#include <stdlib.h>

int main(int argc, char *argv[])
{
    if (argc < 2) {
        printf("Usage: %s <num1> <num2> ... <numN>\n", argv[0]);
        return 1;
    }

    int sum = 0;
    for (int i = 1; i < argc; i++) {
        sum += atoi(argv[i]);
    }

    printf("Sum of %d values: %d\n", argc - 1, sum);
    return 0;
}
  • Run: ./sum 10 20 30
  • Output: Sum of 3 values: 60

Re-derivation: argc = 4 (program name + 3 args). Loop runs i = 1, 2, 3. atoi("10") + atoi("20") + atoi("30") = 60. argc - 1 = 3.

Example 4: Loop through all arguments

#include <stdio.h>

int main(int argc, char *argv[])
{
    printf("Argument list:\n");
    for (int i = 0; i < argc; i++) {
        printf("  argv[%d] = \"%s\"\n", i, argv[i]);
    }
    return 0;
}
  • Run: ./arglist apple banana cherry
  • Output:
Argument list:
  argv[0] = "./arglist"
  argv[1] = "apple"
  argv[2] = "banana"
  argv[3] = "cherry"

Example 5: Safe integer parsing with strtol

#include <stdio.h>
#include <stdlib.h>
#include <errno.h>

int main(int argc, char *argv[])
{
    if (argc < 2) {
        printf("Usage: %s <integer>\n", argv[0]);
        return 1;
    }

    char *endptr;
    errno = 0;
    long val = strtol(argv[1], &endptr, 10);

    if (errno != 0) {
        perror("Overflow/underflow");
        return 1;
    }
    if (*endptr != '\0') {
        printf("Not a valid integer: '%s'\n", argv[1]);
        return 1;
    }

    printf("You entered: %ld\n", val);
    printf("Doubled: %ld\n", val * 2);
    return 0;
}
  • Run: ./parse 42 — Output: You entered: 42 / Doubled: 84
  • Run: ./parse abc — Output: Not a valid integer: 'abc'
  • Run: ./parse 12xyz — Output: Not a valid integer: '12xyz'

The third case is where atoi silently returns 12, discarding "xyz". strtol catches it because endptr points to 'x', not '\0'.

This distinction matters in TCS coding rounds when the problem statement says “read an integer from the command line.” Using atoi will pass all test cases (since the judge feeds valid integers), but an interviewer asking follow-up questions about edge cases expects you to know the strtol alternative.

One more detail: strtol takes a third parameter (base) that specifies the number system. Pass 10 for decimal, 16 for hexadecimal, or 0 to let the function auto-detect based on prefix (0x for hex, 0 for octal, decimal otherwise). For TCS problems, base 10 is almost always correct.

Common Bugs Students Hit

These errors appear repeatedly in TCS coding submissions and often cost marks even when the core logic is correct. Each one is easy to fix once you know the pattern, so review them before your next mock test.

  • Off-by-one on argv indexing. If the problem says “read two numbers from the command line,” those numbers are argv[1] and argv[2], not argv[0] and argv[1]. Forgetting that argv[0] is the program name is the single most common mistake in TCS coding submissions that use command-line input.
  • Missing the argc < 2 guard. Without a check, running the program with no arguments dereferences argv[1] — undefined behavior that may segfault or silently read garbage. The convention: argc < 2 means no user arguments were passed.
  • Assuming atoi returns -1 on error. It does not. atoi("hello") returns 0. If your program treats 0 as a special “error” value, you’ve introduced a bug for any input that legitimately equals 0.
  • Forgetting #include <stdlib.h>. Both atoi and strtol are declared in <stdlib.h>. Omitting the header means the compiler assumes int return type and may truncate long values from strtol.
  • Using atol when atoi suffices. The legacy version of this article used atol() (string-to-long) for values that fit in int. This works but confuses students about the actual return type. Use atoi for int-range values, strtol when you need overflow detection or long range.

For more TCS coding patterns and worked problems, see the TCS coding questions collection and the TCS NQT question pattern guide.

AI in TCS Hiring 2026

TCS coding rounds still test fundamentals like command-line argument parsing. But the hiring mix has shifted: 60% of FY26 fresher hires are AI-skilled, up from 10-15% three years ago, per TCS CHRO Sudeep Kunnumal at the AI Impact Summit. The Prime track (₹9-11 LPA at entry) now expects AI project exposure alongside the C/Java fundamentals you’re drilling here.

The strtol pattern above is about the same instinct that matters in AI engineering: validate your inputs, handle edge cases, don’t trust defaults. If you want to test that instinct on an actual LLM project, TinkerLLM (₹299) gives you a sandbox where you parse model outputs the way this article parses argv. Check for garbage, handle the unexpected, build something that doesn’t silently break.

Primary sources

Frequently asked questions

What is the difference between atoi and strtol in C?

atoi returns 0 on invalid input and provides no way to distinguish a legitimate zero from an error. strtol sets errno on overflow and returns a pointer to the first unconverted character, letting you detect bad input reliably.

Why does argc always have a value of at least 1?

The C standard guarantees that argv[0] holds the program name (or an empty string if the name is unavailable). This means argc is always at least 1 even when the user passes zero additional arguments.

Can command line arguments be integers directly in C?

No. All command line arguments arrive as null-terminated strings in argv. You must convert them to integers explicitly using atoi, atol, or strtol before performing arithmetic.

What happens if the user passes fewer arguments than the program expects?

Accessing argv beyond the actual argument count is undefined behavior. Always check argc before reading argv entries — for example, guard with if (argc < 2) to confirm at least one user argument exists.

Is argv[argc] safe to access?

Yes. The C standard (ISO 9899 section 5.1.2.2.1) guarantees that argv[argc] is a null pointer. Programs sometimes use this as a sentinel in loops that iterate over arguments.

Build AI projects

A self-paced playground for building with LLMs.

TinkerLLM is FACE Prep's sister property. A guided environment for shipping real LLM applications, the kind of project that earns a paragraph on your resume, not a line.

Try TinkerLLM (₹299 launch)
Free AI Roadmap PDF