C and C++ have historically been the most widely used languages in TCS coding rounds, and they remain the dominant choice for experienced competitive programmers sitting the NQT. The TCS iON platform runs a GCC-type compiler, which means standard C99/C11 and C++14/C++17 code compiles cleanly. But there is one aspect of TCS coding that catches unprepared candidates completely off guard: command line argument input. While most candidates have practised programs that use scanf or cin for input, TCS problems frequently pass input through command line arguments - a different reading method that requires knowing argc, argv, and atoi. This guide covers everything: the compiler environment, the command line input method explained from first principles, and a structured set of problems with complete solutions in both C and C++.

The TCS iON Compiler Environment
Compiler Type and Language Versions
TCS iON uses a GCC-based compiler. For C, this means C99 and C11 standards are supported. For C++, C++14 and C++17 are available. Practically speaking:
In C: You can use // single-line comments (C99 feature), variable-length arrays in some contexts, and the standard library headers (stdio.h, stdlib.h, string.h, math.h).
In C++: You can use the full STL (vectors, maps, sets, queues, stacks, algorithms), auto keyword, range-based for loops, lambda functions, and structured bindings (C++17). The bits/stdc++.h mega-header that includes all standard headers is available and widely used by competitive programmers.
C vs C++ on TCS Platform: When to Use Which
Use C when:
- You want to demonstrate foundational programming knowledge in a Ninja interview context
- The problem is simple arithmetic, loops, and conditionals with no complex data structures
- You are more comfortable with C from your academic background
Use C++ when:
- The problem involves sorting (use
std::sortinstead of writing bubble sort) - You need dynamic arrays (
vector<int>instead of manual malloc) - String operations are complex (C++
stringclass vs C character arrays) - The problem has multiple test cases or complex input (STL containers simplify management)
The practical recommendation: If you are comfortable with C++, use it exclusively. The STL saves significant lines of code and reduces bugs. If you only know C, use C - a correct C solution is always better than a buggy C++ solution.
Output Formatting: The Critical Rule
TCS iON evaluates output by exact string matching against expected output. Every character matters.
Rules to follow:
- Print exactly what the problem asks for. If the problem says “print the result”, print the number and nothing else.
- Use
\nfor newlines (notendlin tight loops -endlflushes the buffer and is slower, though for TCS problems this rarely matters) - No trailing spaces after the last value on a line
- No extra blank lines unless the problem specifies them
- If the problem shows sample output with a specific format, match it exactly
Common output error: Adding a descriptive label (“The answer is: 42”) when the expected output is just “42”. This causes a wrong answer even though the calculation is correct.
The Most Important TCS-Specific Concept: Command Line Arguments
Why Command Line Input Is Used
TCS’s iON platform frequently passes test case inputs via command line arguments rather than standard input (keyboard/pipe). This design allows the platform to run automated test cases efficiently. A candidate who only knows scanf or cin will produce programs that compile but receive no input - causing wrong answers on all test cases.
What Are Command Line Arguments?
When you run a program, you can pass values after the executable name:
./program 5 10 hello
Here 5, 10, and hello are command line arguments. Inside the program, these are accessible through the main function parameters argc and argv.
The main() Signature with argc and argv
int main(int argc, char *argv[]) {
// argc = argument count (number of arguments including the program name)
// argv = argument vector (array of strings)
// argv[0] = program name
// argv[1] = first argument
// argv[2] = second argument
// ...
}
Critical facts:
argcalways includes the program name itself. If you run./program 5 10, thenargc = 3(program, 5, 10) andargv[0] = "./program",argv[1] = "5",argv[2] = "10".- All arguments arrive as strings (
char *). The number5arrives as the string"5". To use it as an integer, you must convert it. argvis an array ofchar *pointers - each element is a C string (null-terminated character array).
The atoi() Function: String to Integer Conversion
atoi (ASCII to Integer) converts a C string to an integer:
#include <stdlib.h>
int n = atoi(argv[1]); // converts "42" to the integer 42
How atoi works: It reads digits from the string until it encounters a non-digit character. Leading whitespace is skipped. atoi("42") = 42. atoi("-17") = -17. atoi("0") = 0. atoi("abc") = 0 (no digits found).
For floating point: Use atof() (string to double). atof("3.14") = 3.14.
For long integers: Use atol() or strtol() for more precise control.
Complete Command Line Input Example
#include <stdio.h>
#include <stdlib.h>
int main(int argc, char *argv[]) {
// Check that we received the expected number of arguments
if (argc < 3) {
printf("Usage: %s num1 num2\n", argv[0]);
return 1;
}
int a = atoi(argv[1]); // first argument as integer
int b = atoi(argv[2]); // second argument as integer
printf("%d\n", a + b);
return 0;
}
Running: ./program 15 27 → Output: 42
Reading Multiple Numbers from a Single Argument
Some TCS problems pass all numbers as space-separated values in a single argument wrapped in quotes, or as separate arguments. The pattern depends on the specific problem statement.
Multiple separate arguments (most common):
./program 3 7 2 8 5
Access: argv[1] = “3”, argv[2] = “7”, etc. Loop from argv[1] to argv[argc-1].
Array input as separate arguments:
int arr[100];
int n = argc - 1; // number of integers
for (int i = 0; i < n; i++) {
arr[i] = atoi(argv[i + 1]);
}
When to Use scanf/cin vs Command Line Arguments
Read the problem statement carefully. If the problem says:
- “The input is given as command line arguments” → use
argc/argv/atoi - “Read from standard input” or shows a sample input below → use
scanf/cin - No explicit instruction → use command line arguments (safer default for TCS)
Part 1: Command Line Programming Fundamentals
Problem CL-1: Sum of Two Numbers
Problem statement: Write a program that accepts two integers as command line arguments and prints their sum.
Input: Two integers passed as command line arguments. Output: Their sum on a single line.
C Solution:
#include <stdio.h>
#include <stdlib.h>
int main(int argc, char *argv[]) {
int a = atoi(argv[1]);
int b = atoi(argv[2]);
printf("%d\n", a + b);
return 0;
}
C++ Solution:
#include <iostream>
#include <cstdlib>
using namespace std;
int main(int argc, char *argv[]) {
int a = atoi(argv[1]);
int b = atoi(argv[2]);
cout << a + b << "\n";
return 0;
}
Common error: Using printf("%s\n", argv[1] + argv[2]) - you cannot add C strings with +. Convert to integers first.
Problem CL-2: Sum of N Numbers
Problem statement: The first command line argument is N (count of numbers). The next N arguments are the numbers. Print their sum.
Input: ./program 5 3 7 2 8 5 (N=5, numbers are 3,7,2,8,5)
Output: 25
C Solution:
#include <stdio.h>
#include <stdlib.h>
int main(int argc, char *argv[]) {
int n = atoi(argv[1]);
int sum = 0;
for (int i = 2; i <= n + 1; i++) {
sum += atoi(argv[i]);
}
printf("%d\n", sum);
return 0;
}
C++ Solution:
#include <iostream>
#include <cstdlib>
using namespace std;
int main(int argc, char *argv[]) {
int n = atoi(argv[1]);
int sum = 0;
for (int i = 2; i <= n + 1; i++) {
sum += atoi(argv[i]);
}
cout << sum << "\n";
return 0;
}
Explanation: argv[1] is N (the count), so the actual numbers start at argv[2] through argv[n+1].
Problem CL-3: Processing a String Argument
Problem statement: Accept a string as a command line argument. Print the string in reverse and its length.
C Solution:
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
int main(int argc, char *argv[]) {
char *s = argv[1];
int len = strlen(s);
// Print in reverse
for (int i = len - 1; i >= 0; i--) {
printf("%c", s[i]);
}
printf("\n%d\n", len);
return 0;
}
C++ Solution:
#include <iostream>
#include <string>
using namespace std;
int main(int argc, char *argv[]) {
string s = argv[1]; // convert char* to C++ string
int len = s.length();
// Reverse using built-in
string rev = string(s.rbegin(), s.rend());
cout << rev << "\n" << len << "\n";
return 0;
}
Part 2: Basic Programs
Problem B-1: Prime Number Check
Problem statement: Given a positive integer N, determine if it is prime. Print “Prime” or “Not Prime”.
C Solution (command line input):
#include <stdio.h>
#include <stdlib.h>
#include <math.h>
int isPrime(int n) {
if (n <= 1) return 0;
if (n == 2) return 1;
if (n % 2 == 0) return 0;
for (int i = 3; i <= (int)sqrt((double)n); i += 2) {
if (n % i == 0) return 0;
}
return 1;
}
int main(int argc, char *argv[]) {
int n = atoi(argv[1]);
printf("%s\n", isPrime(n) ? "Prime" : "Not Prime");
return 0;
}
Compile note for C: When using math.h, compile with -lm flag: gcc program.c -o program -lm. TCS iON handles this automatically.
C++ Solution:
#include <iostream>
#include <cmath>
#include <cstdlib>
using namespace std;
bool isPrime(int n) {
if (n <= 1) return false;
if (n == 2) return true;
if (n % 2 == 0) return false;
for (int i = 3; i <= (int)sqrt((double)n); i += 2) {
if (n % i == 0) return false;
}
return true;
}
int main(int argc, char *argv[]) {
int n = atoi(argv[1]);
cout << (isPrime(n) ? "Prime" : "Not Prime") << "\n";
return 0;
}
Why sqrt(n) as the loop bound: If N has a factor greater than sqrt(N), it must have a corresponding factor smaller than sqrt(N). So checking up to sqrt(N) is sufficient to find all factors.
Edge cases: 0 and 1 are not prime. 2 is the only even prime. Negative numbers are not prime.
Problem B-2: Palindrome Number
Problem statement: Check if a given integer is a palindrome (reads the same forwards and backwards). Print “Palindrome” or “Not Palindrome”.
C Solution:
#include <stdio.h>
#include <stdlib.h>
int isPalindrome(int n) {
if (n < 0) return 0; // negative numbers are not palindromes
int original = n;
int reversed = 0;
while (n > 0) {
int digit = n % 10; // extract last digit
reversed = reversed * 10 + digit; // build reversed number
n /= 10; // remove last digit
}
return original == reversed;
}
int main(int argc, char *argv[]) {
int n = atoi(argv[1]);
printf("%s\n", isPalindrome(n) ? "Palindrome" : "Not Palindrome");
return 0;
}
C++ Solution:
#include <iostream>
#include <cstdlib>
using namespace std;
bool isPalindrome(int n) {
if (n < 0) return false;
int original = n, reversed = 0;
while (n > 0) {
reversed = reversed * 10 + n % 10;
n /= 10;
}
return original == reversed;
}
int main(int argc, char *argv[]) {
int n = atoi(argv[1]);
cout << (isPalindrome(n) ? "Palindrome" : "Not Palindrome") << "\n";
return 0;
}
Alternative C++ approach using strings:
#include <iostream>
#include <string>
#include <algorithm>
#include <cstdlib>
using namespace std;
int main(int argc, char *argv[]) {
string s = argv[1];
string rev = s;
reverse(rev.begin(), rev.end());
cout << (s == rev ? "Palindrome" : "Not Palindrome") << "\n";
return 0;
}
Problem B-3: Fibonacci Series
Problem statement: Print the first N terms of the Fibonacci series.
C Solution:
#include <stdio.h>
#include <stdlib.h>
int main(int argc, char *argv[]) {
int n = atoi(argv[1]);
if (n <= 0) { printf("Invalid input\n"); return 1; }
long long a = 0, b = 1;
for (int i = 0; i < n; i++) {
printf("%lld", a);
if (i < n - 1) printf(" ");
long long next = a + b;
a = b;
b = next;
}
printf("\n");
return 0;
}
C++ Solution:
#include <iostream>
#include <cstdlib>
using namespace std;
int main(int argc, char *argv[]) {
int n = atoi(argv[1]);
long long a = 0, b = 1;
for (int i = 0; i < n; i++) {
cout << a;
if (i < n - 1) cout << " ";
long long next = a + b;
a = b;
b = next;
}
cout << "\n";
return 0;
}
Why long long: Fibonacci numbers grow exponentially. int overflows around F(46). long long handles up to approximately F(92).
Problem B-4: Armstrong Number
Problem statement: Check if a number is an Armstrong number (sum of each digit raised to the power of the number of digits equals the number itself). Example: 153 = 1^3 + 5^3 + 3^3.
C Solution:
#include <stdio.h>
#include <stdlib.h>
#include <math.h>
int isArmstrong(int n) {
int original = n;
int digits = 0;
int temp = n;
// Count digits
while (temp > 0) { digits++; temp /= 10; }
// Sum of digits^(digit_count)
int sum = 0;
temp = n;
while (temp > 0) {
int d = temp % 10;
sum += (int)pow((double)d, digits);
temp /= 10;
}
return sum == original;
}
int main(int argc, char *argv[]) {
int n = atoi(argv[1]);
printf("%s\n", isArmstrong(n) ? "Armstrong" : "Not Armstrong");
return 0;
}
C++ Solution:
#include <iostream>
#include <cmath>
#include <cstdlib>
using namespace std;
bool isArmstrong(int n) {
int original = n, digits = 0, temp = n;
while (temp > 0) { digits++; temp /= 10; }
int sum = 0;
temp = n;
while (temp > 0) {
int d = temp % 10;
sum += (int)pow((double)d, digits);
temp /= 10;
}
return sum == original;
}
int main(int argc, char *argv[]) {
int n = atoi(argv[1]);
cout << (isArmstrong(n) ? "Armstrong" : "Not Armstrong") << "\n";
return 0;
}
Problem B-5: Factorial
Problem statement: Compute the factorial of N.
C Solution (iterative):
#include <stdio.h>
#include <stdlib.h>
int main(int argc, char *argv[]) {
int n = atoi(argv[1]);
unsigned long long fact = 1;
for (int i = 2; i <= n; i++) {
fact *= i;
}
printf("%llu\n", fact);
return 0;
}
C Solution (recursive):
#include <stdio.h>
#include <stdlib.h>
unsigned long long factorial(int n) {
if (n <= 1) return 1;
return n * factorial(n - 1);
}
int main(int argc, char *argv[]) {
int n = atoi(argv[1]);
printf("%llu\n", factorial(n));
return 0;
}
C++ Solution:
#include <iostream>
#include <cstdlib>
using namespace std;
int main(int argc, char *argv[]) {
int n = atoi(argv[1]);
unsigned long long fact = 1;
for (int i = 2; i <= n; i++) fact *= i;
cout << fact << "\n";
return 0;
}
Overflow note: unsigned long long holds 20! = 2,432,902,008,176,640,000. For N > 20, you need big integer arithmetic (not available natively in C/C++).
Problem B-6: Digit Sum and Digit Reversal
Problem statement: Given a number, print its digit sum and its reversed form.
C Solution:
#include <stdio.h>
#include <stdlib.h>
int main(int argc, char *argv[]) {
int n = atoi(argv[1]);
int original = n;
int sum = 0, reversed = 0;
while (n > 0) {
int d = n % 10;
sum += d;
reversed = reversed * 10 + d;
n /= 10;
}
printf("Digit sum: %d\nReversed: %d\n", sum, reversed);
return 0;
}
C++ Solution:
#include <iostream>
#include <cstdlib>
using namespace std;
int main(int argc, char *argv[]) {
int n = atoi(argv[1]);
int sum = 0, reversed = 0;
int temp = n;
while (temp > 0) {
int d = temp % 10;
sum += d;
reversed = reversed * 10 + d;
temp /= 10;
}
cout << "Digit sum: " << sum << "\nReversed: " << reversed << "\n";
return 0;
}
Part 3: String Programs
Problem S-1: String Reversal
Problem statement: Reverse a given string.
C Solution:
#include <stdio.h>
#include <string.h>
int main(int argc, char *argv[]) {
char *s = argv[1];
int len = strlen(s);
// In-place reversal
for (int i = 0; i < len / 2; i++) {
char temp = s[i];
s[i] = s[len - 1 - i];
s[len - 1 - i] = temp;
}
printf("%s\n", s);
return 0;
}
C++ Solution:
#include <iostream>
#include <string>
#include <algorithm>
using namespace std;
int main(int argc, char *argv[]) {
string s = argv[1];
reverse(s.begin(), s.end());
cout << s << "\n";
return 0;
}
Problem S-2: Vowel and Consonant Count
Problem statement: Count the number of vowels and consonants in a string.
C Solution:
#include <stdio.h>
#include <ctype.h>
int isVowel(char c) {
c = tolower(c);
return (c == 'a' || c == 'e' || c == 'i' || c == 'o' || c == 'u');
}
int main(int argc, char *argv[]) {
char *s = argv[1];
int vowels = 0, consonants = 0;
for (int i = 0; s[i] != '\0'; i++) {
if (isalpha(s[i])) {
if (isVowel(s[i])) vowels++;
else consonants++;
}
}
printf("Vowels: %d\nConsonants: %d\n", vowels, consonants);
return 0;
}
C++ Solution:
#include <iostream>
#include <string>
#include <cctype>
using namespace std;
int main(int argc, char *argv[]) {
string s = argv[1];
string vowelSet = "aeiouAEIOU";
int vowels = 0, consonants = 0;
for (char c : s) {
if (isalpha(c)) {
if (vowelSet.find(c) != string::npos) vowels++;
else consonants++;
}
}
cout << "Vowels: " << vowels << "\nConsonants: " << consonants << "\n";
return 0;
}
Problem S-3: Character Frequency
Problem statement: Find the frequency of each character in a string.
C Solution:
#include <stdio.h>
#include <string.h>
int main(int argc, char *argv[]) {
char *s = argv[1];
int freq[256] = {0}; // ASCII character array
for (int i = 0; s[i] != '\0'; i++) {
freq[(unsigned char)s[i]]++;
}
for (int i = 0; i < 256; i++) {
if (freq[i] > 0) {
printf("%c: %d\n", (char)i, freq[i]);
}
}
return 0;
}
C++ Solution:
#include <iostream>
#include <map>
#include <string>
using namespace std;
int main(int argc, char *argv[]) {
string s = argv[1];
map<char, int> freq;
for (char c : s) freq[c]++;
for (auto &p : freq) {
cout << p.first << ": " << p.second << "\n";
}
return 0;
}
C++ note: Using map<char, int> automatically sorts output by character. The C version uses an array indexed by ASCII value, which also produces sorted output (ASCII order).
Problem S-4: String Palindrome Check (Without Library)
Problem statement: Check if a string is a palindrome without using reverse() or similar library functions.
C Solution:
#include <stdio.h>
#include <string.h>
int main(int argc, char *argv[]) {
char *s = argv[1];
int len = strlen(s);
int isPalin = 1;
for (int i = 0; i < len / 2; i++) {
if (s[i] != s[len - 1 - i]) {
isPalin = 0;
break;
}
}
printf("%s\n", isPalin ? "Palindrome" : "Not Palindrome");
return 0;
}
C++ Solution:
#include <iostream>
#include <string>
using namespace std;
int main(int argc, char *argv[]) {
string s = argv[1];
int left = 0, right = (int)s.length() - 1;
bool isPalin = true;
while (left < right) {
if (s[left] != s[right]) { isPalin = false; break; }
left++; right--;
}
cout << (isPalin ? "Palindrome" : "Not Palindrome") << "\n";
return 0;
}
Part 4: Array Programs
Problem A-1: Sort an Array
Problem statement: Given N numbers, sort them in ascending order.
C Solution (Bubble Sort - for demonstration):
#include <stdio.h>
#include <stdlib.h>
void bubbleSort(int arr[], int n) {
for (int i = 0; i < n - 1; i++) {
for (int j = 0; j < n - i - 1; j++) {
if (arr[j] > arr[j + 1]) {
int temp = arr[j];
arr[j] = arr[j + 1];
arr[j + 1] = temp;
}
}
}
}
int compare(const void *a, const void *b) {
return (*(int*)a - *(int*)b);
}
int main(int argc, char *argv[]) {
int n = argc - 1;
int arr[100];
for (int i = 0; i < n; i++) arr[i] = atoi(argv[i + 1]);
// Use qsort (stdlib.h) for efficiency - O(N log N)
qsort(arr, n, sizeof(int), compare);
for (int i = 0; i < n; i++) {
printf("%d", arr[i]);
if (i < n - 1) printf(" ");
}
printf("\n");
return 0;
}
C++ Solution:
#include <iostream>
#include <vector>
#include <algorithm>
#include <cstdlib>
using namespace std;
int main(int argc, char *argv[]) {
int n = argc - 1;
vector<int> arr(n);
for (int i = 0; i < n; i++) arr[i] = atoi(argv[i + 1]);
sort(arr.begin(), arr.end());
for (int i = 0; i < n; i++) {
cout << arr[i];
if (i < n - 1) cout << " ";
}
cout << "\n";
return 0;
}
When to use which sort in C:
qsort(fromstdlib.h): general purpose, O(N log N) average, requires a comparator function- Manual bubble sort: only for very small arrays (N < 10) or when the problem explicitly asks for bubble sort
Problem A-2: Find Maximum and Minimum
C Solution:
#include <stdio.h>
#include <stdlib.h>
#include <limits.h>
int main(int argc, char *argv[]) {
int n = argc - 1;
int maxVal = INT_MIN, minVal = INT_MAX;
for (int i = 1; i < argc; i++) {
int val = atoi(argv[i]);
if (val > maxVal) maxVal = val;
if (val < minVal) minVal = val;
}
printf("Max: %d\nMin: %d\n", maxVal, minVal);
return 0;
}
C++ Solution:
#include <iostream>
#include <vector>
#include <algorithm>
#include <cstdlib>
#include <climits>
using namespace std;
int main(int argc, char *argv[]) {
vector<int> arr;
for (int i = 1; i < argc; i++) arr.push_back(atoi(argv[i]));
cout << "Max: " << *max_element(arr.begin(), arr.end()) << "\n";
cout << "Min: " << *min_element(arr.begin(), arr.end()) << "\n";
return 0;
}
Problem A-3: Array Rotation
Problem statement: Rotate an array of N elements left by K positions.
C Solution:
#include <stdio.h>
#include <stdlib.h>
void rotateLeft(int arr[], int n, int k) {
k = k % n; // handle k >= n
// Reverse first k elements
for (int i = 0, j = k - 1; i < j; i++, j--) {
int temp = arr[i]; arr[i] = arr[j]; arr[j] = temp;
}
// Reverse remaining n-k elements
for (int i = k, j = n - 1; i < j; i++, j--) {
int temp = arr[i]; arr[i] = arr[j]; arr[j] = temp;
}
// Reverse entire array
for (int i = 0, j = n - 1; i < j; i++, j--) {
int temp = arr[i]; arr[i] = arr[j]; arr[j] = temp;
}
}
int main(int argc, char *argv[]) {
// First argument is k, remaining are array elements
int k = atoi(argv[1]);
int n = argc - 2;
int arr[100];
for (int i = 0; i < n; i++) arr[i] = atoi(argv[i + 2]);
rotateLeft(arr, n, k);
for (int i = 0; i < n; i++) {
printf("%d", arr[i]);
if (i < n - 1) printf(" ");
}
printf("\n");
return 0;
}
C++ Solution:
#include <iostream>
#include <vector>
#include <algorithm>
#include <cstdlib>
using namespace std;
int main(int argc, char *argv[]) {
int k = atoi(argv[1]);
vector<int> arr;
for (int i = 2; i < argc; i++) arr.push_back(atoi(argv[i]));
int n = arr.size();
k = k % n;
rotate(arr.begin(), arr.begin() + k, arr.end());
for (int i = 0; i < n; i++) {
cout << arr[i];
if (i < n - 1) cout << " ";
}
cout << "\n";
return 0;
}
Part 5: Pattern Programs
Pattern printing uses nested loops. TCS occasionally tests these to verify basic loop control.
Problem P-1: Number Triangle
Problem statement: Print a number triangle of N rows.
1
1 2
1 2 3
1 2 3 4
C Solution:
#include <stdio.h>
#include <stdlib.h>
int main(int argc, char *argv[]) {
int n = atoi(argv[1]);
for (int i = 1; i <= n; i++) {
for (int j = 1; j <= i; j++) {
printf("%d", j);
if (j < i) printf(" ");
}
printf("\n");
}
return 0;
}
C++ Solution:
#include <iostream>
#include <cstdlib>
using namespace std;
int main(int argc, char *argv[]) {
int n = atoi(argv[1]);
for (int i = 1; i <= n; i++) {
for (int j = 1; j <= i; j++) {
cout << j;
if (j < i) cout << " ";
}
cout << "\n";
}
return 0;
}
Problem P-2: Star Pyramid
Problem statement: Print a star pyramid of N rows.
*
***
*****
*******
*********
C Solution:
#include <stdio.h>
#include <stdlib.h>
int main(int argc, char *argv[]) {
int n = atoi(argv[1]);
for (int i = 1; i <= n; i++) {
// Print spaces
for (int j = 1; j <= n - i; j++) printf(" ");
// Print stars (2*i - 1 stars)
for (int j = 1; j <= 2 * i - 1; j++) printf("*");
printf("\n");
}
return 0;
}
C++ Solution:
#include <iostream>
#include <string>
#include <cstdlib>
using namespace std;
int main(int argc, char *argv[]) {
int n = atoi(argv[1]);
for (int i = 1; i <= n; i++) {
cout << string(n - i, ' ') << string(2 * i - 1, '*') << "\n";
}
return 0;
}
Part 6: Mathematical Programs
Problem M-1: GCD and LCM
C Solution:
#include <stdio.h>
#include <stdlib.h>
int gcd(int a, int b) {
while (b != 0) {
int temp = b;
b = a % b;
a = temp;
}
return a;
}
int main(int argc, char *argv[]) {
int a = atoi(argv[1]);
int b = atoi(argv[2]);
int g = gcd(a, b);
int l = (a / g) * b; // a/g first to reduce overflow risk
printf("GCD: %d\nLCM: %d\n", g, l);
return 0;
}
C++ Solution:
#include <iostream>
#include <numeric> // for std::gcd in C++17
#include <cstdlib>
using namespace std;
int main(int argc, char *argv[]) {
int a = atoi(argv[1]), b = atoi(argv[2]);
int g = __gcd(a, b); // C++ built-in (or std::gcd in C++17)
int l = (a / g) * b;
cout << "GCD: " << g << "\nLCM: " << l << "\n";
return 0;
}
Problem M-2: Binary Conversion
Problem statement: Convert a decimal number to binary.
C Solution:
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
int main(int argc, char *argv[]) {
int n = atoi(argv[1]);
if (n == 0) { printf("0\n"); return 0; }
char binary[64];
int pos = 0;
while (n > 0) {
binary[pos++] = '0' + (n % 2);
n /= 2;
}
// Reverse the binary string
for (int i = 0; i < pos / 2; i++) {
char temp = binary[i];
binary[i] = binary[pos - 1 - i];
binary[pos - 1 - i] = temp;
}
binary[pos] = '\0';
printf("%s\n", binary);
return 0;
}
C++ Solution:
#include <iostream>
#include <bitset>
#include <cstdlib>
using namespace std;
int main(int argc, char *argv[]) {
int n = atoi(argv[1]);
// Using bitset for clean binary conversion
cout << bitset<32>(n).to_string().substr(bitset<32>(n).to_string().find('1')) << "\n";
return 0;
}
Or the manual approach in C++:
string toBinary(int n) {
if (n == 0) return "0";
string result = "";
while (n > 0) { result = char('0' + n % 2) + result; n /= 2; }
return result;
}
Problem M-3: Matrix Addition
Problem statement: Add two 2x2 matrices. Input: 8 numbers (row-major order for each matrix).
C Solution:
#include <stdio.h>
#include <stdlib.h>
int main(int argc, char *argv[]) {
int a[2][2], b[2][2], c[2][2];
// Read first matrix
for (int i = 0; i < 2; i++)
for (int j = 0; j < 2; j++)
a[i][j] = atoi(argv[1 + i * 2 + j]);
// Read second matrix
for (int i = 0; i < 2; i++)
for (int j = 0; j < 2; j++)
b[i][j] = atoi(argv[5 + i * 2 + j]);
// Add
for (int i = 0; i < 2; i++)
for (int j = 0; j < 2; j++)
c[i][j] = a[i][j] + b[i][j];
// Print
for (int i = 0; i < 2; i++) {
for (int j = 0; j < 2; j++) {
printf("%d", c[i][j]);
if (j < 1) printf(" ");
}
printf("\n");
}
return 0;
}
Part 7: Advanced Programs
Problem ADV-1: Recursive Sum of Digits
Problem statement: Find the digital root of a number (recursively sum digits until single digit).
C Solution:
#include <stdio.h>
#include <stdlib.h>
int digitSum(int n) {
if (n < 10) return n;
int sum = 0;
while (n > 0) { sum += n % 10; n /= 10; }
return digitSum(sum);
}
int main(int argc, char *argv[]) {
int n = atoi(argv[1]);
printf("%d\n", digitSum(n));
return 0;
}
C++ Solution:
#include <iostream>
#include <cstdlib>
using namespace std;
int digitRoot(int n) {
if (n < 10) return n;
int sum = 0;
while (n > 0) { sum += n % 10; n /= 10; }
return digitRoot(sum);
}
int main(int argc, char *argv[]) {
cout << digitRoot(atoi(argv[1])) << "\n";
return 0;
}
Mathematical shortcut: The digital root of N is: 0 if N=0, 9 if N%9==0, else N%9. This O(1) formula replaces the recursive approach for large inputs.
Problem ADV-2: Two Array Intersection
Problem statement: Find common elements between two arrays.
C++ Solution (using sets):
#include <iostream>
#include <set>
#include <cstdlib>
using namespace std;
int main(int argc, char *argv[]) {
// First arg: N (size of first array), next N args: first array
// Then M (size of second array), next M args: second array
int n = atoi(argv[1]);
set<int> setA;
for (int i = 2; i <= n + 1; i++) setA.insert(atoi(argv[i]));
int m = atoi(argv[n + 2]);
bool first = true;
for (int i = n + 3; i <= n + 2 + m; i++) {
int val = atoi(argv[i]);
if (setA.count(val)) {
if (!first) cout << " ";
cout << val;
first = false;
setA.erase(val); // prevent duplicates in output
}
}
cout << "\n";
return 0;
}
Problem ADV-3: Bit Manipulation - Count Set Bits
Problem statement: Count the number of 1-bits in the binary representation of N.
C Solution:
#include <stdio.h>
#include <stdlib.h>
int countBits(int n) {
int count = 0;
while (n) {
count += n & 1; // check last bit
n >>= 1; // shift right
}
return count;
}
// Alternatively: Brian Kernighan's algorithm (faster)
int countBitsFast(int n) {
int count = 0;
while (n) {
n &= (n - 1); // clears the lowest set bit
count++;
}
return count;
}
int main(int argc, char *argv[]) {
int n = atoi(argv[1]);
printf("%d\n", countBitsFast(n));
return 0;
}
C++ Solution:
#include <iostream>
#include <bitset>
#include <cstdlib>
using namespace std;
int main(int argc, char *argv[]) {
int n = atoi(argv[1]);
cout << __builtin_popcount(n) << "\n"; // GCC built-in
return 0;
}
__builtin_popcount is a GCC compiler intrinsic that counts set bits. Since TCS uses GCC, this is available and is the fastest option.
C/C++ Quick Reference for TCS iON
C Standard Library Headers
| Header | Key functions |
|---|---|
stdio.h |
printf, scanf, fprintf, fgets |
stdlib.h |
atoi, atof, atol, malloc, free, qsort, abs |
string.h |
strlen, strcpy, strcat, strcmp, strchr, strstr, memset |
math.h |
sqrt, pow, abs, floor, ceil, log, sin, cos |
ctype.h |
isalpha, isdigit, isupper, islower, toupper, tolower |
limits.h |
INT_MAX, INT_MIN, LLONG_MAX, LLONG_MIN |
C++ STL Quick Reference
// Vector (dynamic array)
vector<int> v;
v.push_back(5); // add to back
v.pop_back(); // remove from back
v.size(); // number of elements
v[i]; // access by index
sort(v.begin(), v.end()); // sort ascending
sort(v.begin(), v.end(), greater<int>()); // sort descending
// String
string s = "hello";
s.length(); // length
s.find("ell"); // find substring (npos if not found)
s.substr(1, 3); // substring starting at 1, length 3 = "ell"
s.replace(1, 3, "xyz"); // replace
s += " world"; // concatenate
transform(s.begin(), s.end(), s.begin(), toupper); // uppercase
// Map
map<string, int> m;
m["key"] = 5;
m.count("key"); // 1 if exists, 0 if not
m.find("key"); // iterator, m.end() if not found
for (auto &p : m) { cout << p.first << " " << p.second; }
// Set
set<int> s;
s.insert(5);
s.count(5); // 1 if present, 0 if not
s.erase(5);
// Queue
queue<int> q;
q.push(5); // enqueue
q.front(); // peek front
q.pop(); // dequeue
// Stack
stack<int> st;
st.push(5); // push
st.top(); // peek top
st.pop(); // pop
Common TCS Coding Mistakes
Mistake 1: Off-by-one in command line argument indexing
argv[0] is the program name. Your first data argument is argv[1], not argv[0].
Mistake 2: Not handling negative numbers
atoi("-5") correctly returns -5, but programs that assume inputs are always positive will fail. Check the problem statement for the input range.
Mistake 3: Integer overflow
For problems involving products or sums of large numbers, use long long instead of int. Declare with long long var = 0LL; and use %lld in printf.
Mistake 4: Forgetting string null terminator
C strings end with \0. A char array of size N can hold N-1 characters plus the terminator. Always ensure your string buffer is large enough.
Mistake 5: endl vs “\n” in loops
cout << endl flushes the buffer AND prints a newline. In output-intensive loops, use "\n" which only prints a newline without flushing.
Mistake 6: Array size underestimation
When reading N elements from command line arguments, ensure your array is declared with size at least N. A safe practice: int arr[1000] covers most TCS problem constraints.
Mistake 7: Missing return statement
main must return 0 on success. Some compilers warn but do not error; the TCS compiler may accept or reject missing returns depending on the standard used. Always include return 0;.
Test Strategy for C/C++ on TCS iON
Before Writing Code
-
Read the problem twice. Identify: input format (command line or stdin?), data types needed (int, long long, float?), output format (exact string match required).
-
Write pseudocode on rough paper. Identify the algorithm before writing actual code.
-
Check the constraints. If N can be up to 10^6, an O(N²) algorithm will time out.
While Writing Code
-
Use descriptive variable names even in competitive settings.
nfor count,arrfor array,resultfor the final answer are readable and error-reducing. -
Handle edge cases explicitly at the top of your function: n=0, n=1, negative numbers, empty strings.
-
Test mentally with the sample input before submitting. Trace through your code line by line with the given input and verify the output matches.
After Writing Code
Verify:
- All arguments read from
argv, not fromscanfif the problem specifies command line input - Output matches expected format exactly (no extra spaces, correct newlines)
- No unused variables that might cause compiler warnings
return 0;at the end ofmain
Submit the brute-force solution first if you have one that works on the sample test cases. Then optimise if time permits. A partially-correct solution is always better than a perfectly-written solution that is never submitted.
The C and C++ language combination, mastered to the level demonstrated in this guide, provides complete coverage for TCS NQT Foundation and Ninja coding requirements. For Digital Advanced coding, the same foundations extend naturally into more complex algorithms - but the input handling, output formatting, and structural patterns remain identical.
Part 8: Extended Problem Collection
Problem E-1: Number of Occurrences of Each Digit
Problem statement: Given a number, print how many times each digit (0-9) appears in it.
C Solution:
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
int main(int argc, char *argv[]) {
char *s = argv[1];
int freq[10] = {0};
// Handle negative numbers: skip the minus sign
int start = (s[0] == '-') ? 1 : 0;
for (int i = start; s[i] != '\0'; i++) {
if (s[i] >= '0' && s[i] <= '9') {
freq[s[i] - '0']++;
}
}
for (int i = 0; i <= 9; i++) {
if (freq[i] > 0) {
printf("%d appears %d time(s)\n", i, freq[i]);
}
}
return 0;
}
C++ Solution:
#include <iostream>
#include <map>
#include <cstdlib>
using namespace std;
int main(int argc, char *argv[]) {
string s = argv[1];
map<char, int> freq;
for (char c : s) {
if (c >= '0' && c <= '9') freq[c]++;
}
for (auto &p : freq) {
cout << (p.first - '0') << " appears " << p.second << " time(s)\n";
}
return 0;
}
Problem E-2: Power Without Built-in Function
Problem statement: Compute base^exp using only multiplication (no pow()).
C Solution (iterative):
#include <stdio.h>
#include <stdlib.h>
long long power(long long base, int exp) {
long long result = 1;
while (exp > 0) {
if (exp % 2 == 1) result *= base;
base *= base;
exp /= 2;
}
return result;
}
int main(int argc, char *argv[]) {
long long base = atol(argv[1]);
int exp = atoi(argv[2]);
printf("%lld\n", power(base, exp));
return 0;
}
C++ Solution:
#include <iostream>
#include <cstdlib>
using namespace std;
long long power(long long base, int exp) {
long long result = 1;
while (exp > 0) {
if (exp & 1) result *= base; // same as exp % 2 == 1
base *= base;
exp >>= 1; // same as exp /= 2
}
return result;
}
int main(int argc, char *argv[]) {
long long base = atol(argv[1]);
int exp = atoi(argv[2]);
cout << power(base, exp) << "\n";
return 0;
}
Why this approach (binary exponentiation): Naive repeated multiplication takes O(exp) multiplications. Binary exponentiation exploits the fact that base^8 = (base^4)^2 = ((base^2)^2)^2, reducing to O(log exp) multiplications.
Problem E-3: Check Perfect Number
Problem statement: A perfect number equals the sum of its proper divisors (divisors excluding itself). Is N perfect?
C Solution:
#include <stdio.h>
#include <stdlib.h>
#include <math.h>
int isPerfect(int n) {
if (n <= 1) return 0;
int sum = 1; // 1 is always a proper divisor (for n > 1)
for (int i = 2; i <= (int)sqrt((double)n); i++) {
if (n % i == 0) {
sum += i;
if (i != n / i) sum += n / i; // add both divisors
}
}
return sum == n;
}
int main(int argc, char *argv[]) {
int n = atoi(argv[1]);
printf("%s\n", isPerfect(n) ? "Perfect" : "Not Perfect");
return 0;
}
C++ Solution:
#include <iostream>
#include <cmath>
#include <cstdlib>
using namespace std;
bool isPerfect(int n) {
if (n <= 1) return false;
int sum = 1;
for (int i = 2; i <= (int)sqrt((double)n); i++) {
if (n % i == 0) {
sum += i;
if (i != n / i) sum += n / i;
}
}
return sum == n;
}
int main(int argc, char *argv[]) {
cout << (isPerfect(atoi(argv[1])) ? "Perfect" : "Not Perfect") << "\n";
return 0;
}
Well-known perfect numbers: 6 (1+2+3=6), 28 (1+2+4+7+14=28), 496, 8128.
Problem E-4: Sum of Prime Numbers up to N
Problem statement: Find the sum of all prime numbers from 2 to N using the Sieve of Eratosthenes.
C Solution:
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
int main(int argc, char *argv[]) {
int n = atoi(argv[1]);
char *sieve = (char *)calloc(n + 1, sizeof(char)); // 0 = prime, 1 = composite
// calloc initialises to 0
sieve[0] = 1; sieve[1] = 1; // 0 and 1 are not prime
for (int i = 2; (long long)i * i <= n; i++) {
if (!sieve[i]) {
for (int j = i * i; j <= n; j += i) {
sieve[j] = 1;
}
}
}
long long sum = 0;
for (int i = 2; i <= n; i++) {
if (!sieve[i]) sum += i;
}
printf("%lld\n", sum);
free(sieve);
return 0;
}
C++ Solution:
#include <iostream>
#include <vector>
#include <cstdlib>
using namespace std;
int main(int argc, char *argv[]) {
int n = atoi(argv[1]);
vector<bool> sieve(n + 1, true);
sieve[0] = sieve[1] = false;
for (int i = 2; (long long)i * i <= n; i++) {
if (sieve[i]) {
for (int j = i * i; j <= n; j += i)
sieve[j] = false;
}
}
long long sum = 0;
for (int i = 2; i <= n; i++)
if (sieve[i]) sum += i;
cout << sum << "\n";
return 0;
}
Sieve efficiency: The Sieve of Eratosthenes generates all primes up to N in O(N log log N) time, far faster than checking each number individually.
Problem E-5: Second Largest in Array
Problem statement: Find the second largest element in an array. All elements are distinct.
C Solution:
#include <stdio.h>
#include <stdlib.h>
#include <limits.h>
int main(int argc, char *argv[]) {
int n = argc - 1;
int largest = INT_MIN, second = INT_MIN;
for (int i = 1; i < argc; i++) {
int val = atoi(argv[i]);
if (val > largest) {
second = largest;
largest = val;
} else if (val > second) {
second = val;
}
}
if (second == INT_MIN) {
printf("No second largest\n");
} else {
printf("%d\n", second);
}
return 0;
}
C++ Solution:
#include <iostream>
#include <vector>
#include <algorithm>
#include <cstdlib>
#include <climits>
using namespace std;
int main(int argc, char *argv[]) {
vector<int> arr;
for (int i = 1; i < argc; i++) arr.push_back(atoi(argv[i]));
sort(arr.begin(), arr.end(), greater<int>());
cout << arr[1] << "\n"; // second element after descending sort
return 0;
}
Note: The C solution is O(N) - single pass. The C++ solution using sort is O(N log N). For TCS problem constraints, both work, but the O(N) approach is worth knowing.
Problem E-6: Count Pairs with Given Sum
Problem statement: Count pairs of elements in an array whose sum equals a target value K.
C Solution (O(N²)):
#include <stdio.h>
#include <stdlib.h>
int main(int argc, char *argv[]) {
int k = atoi(argv[1]);
int n = argc - 2;
int arr[100];
for (int i = 0; i < n; i++) arr[i] = atoi(argv[i + 2]);
int count = 0;
for (int i = 0; i < n - 1; i++) {
for (int j = i + 1; j < n; j++) {
if (arr[i] + arr[j] == k) count++;
}
}
printf("%d\n", count);
return 0;
}
C++ Solution (O(N) using map):
#include <iostream>
#include <unordered_map>
#include <cstdlib>
using namespace std;
int main(int argc, char *argv[]) {
int k = atoi(argv[1]);
unordered_map<int, int> freq;
int count = 0;
for (int i = 2; i < argc; i++) {
int val = atoi(argv[i]);
int complement = k - val;
if (freq.count(complement)) {
count += freq[complement];
}
freq[val]++;
}
cout << count << "\n";
return 0;
}
Algorithm: For each element, check if (k - element) has been seen before. If yes, all previous occurrences of (k - element) form valid pairs with the current element.
Part 9: Using Standard Input (scanf/cin) When Required
While TCS often uses command line arguments, some problems specify standard input. The key patterns:
Reading Multiple Lines with scanf
#include <stdio.h>
int main() {
int n;
scanf("%d", &n); // read count
int arr[100];
for (int i = 0; i < n; i++) {
scanf("%d", &arr[i]); // read each element
}
// process...
return 0;
}
Reading Multiple Lines with cin
#include <iostream>
#include <vector>
using namespace std;
int main() {
int n;
cin >> n;
vector<int> arr(n);
for (int i = 0; i < n; i++) cin >> arr[i];
// process...
return 0;
}
Reading a String with Spaces
// Reading a line with spaces in C
char line[1000];
fgets(line, sizeof(line), stdin);
// fgets includes the newline - strip it if needed
line[strcspn(line, "\n")] = '\0';
// Reading a line with spaces in C++
string line;
getline(cin, line);
Important: scanf("%s", str) reads only up to the first whitespace. Use fgets or getline for strings with spaces.
Handling Multiple Test Cases
Some TCS problems provide multiple test cases in a single run. Two common formats:
Format 1: Count then Cases
3 <- number of test cases
5 <- test case 1 input
12 <- test case 2 input
7 <- test case 3 input
C Solution:
#include <stdio.h>
#include <stdlib.h>
int solve(int n) {
// your logic here
return n * n; // example: return square
}
int main(int argc, char *argv[]) {
// If using command line: first arg is count, rest are test cases
int t = atoi(argv[1]);
for (int i = 0; i < t; i++) {
int n = atoi(argv[i + 2]);
printf("%d\n", solve(n));
}
return 0;
}
Format 2: Read Until End of Input (scanf returns EOF)
#include <stdio.h>
int main() {
int n;
while (scanf("%d", &n) != EOF) {
printf("%d\n", n * n); // process each input
}
return 0;
}
#include <iostream>
using namespace std;
int main() {
int n;
while (cin >> n) {
cout << n * n << "\n";
}
return 0;
}
Debugging Common Compile Errors on TCS iON
“implicit declaration of function”
Occurs when a function is used before being declared. Either declare the function before main or add a forward declaration (prototype):
// Add prototype before main:
int isPrime(int n);
int main(int argc, char *argv[]) {
// can now call isPrime
}
int isPrime(int n) { ... }
“undefined reference to sqrt/pow”
The math functions require explicit linking with -lm. TCS iON handles this automatically, but if you see this error in your local testing: gcc program.c -o program -lm.
Segmentation Fault (Runtime Error)
Most common causes:
- Array access out of bounds (arr[-1] or arr[n] when valid is arr[0] to arr[n-1])
- Dereferencing a null pointer
- Stack overflow from infinite recursion
Debugging locally:
gcc -g program.c -o program # compile with debug info
./program args # run and see where it crashes
Or add print statements before and after the suspected crash point to locate it.
“format ‘%d’ expects argument of type ‘int’ but argument is of type ‘long long’”
This is a common mismatch. Use %lld for long long, %d for int, %f for float, %lf for double.
Complete Program Template: C and C++
C Template (Command Line Input)
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <math.h>
#include <ctype.h>
#include <limits.h>
/* Helper functions go here */
int main(int argc, char *argv[]) {
/* Read inputs */
int n = atoi(argv[1]); // adjust based on problem
/* Process */
/* Output */
printf("%d\n", n); // adjust based on expected output
return 0;
}
C++ Template (Command Line Input)
#include <bits/stdc++.h>
using namespace std;
typedef long long ll;
int main(int argc, char *argv[]) {
ios_base::sync_with_stdio(false);
cin.tie(NULL);
/* Read inputs from command line */
int n = atoi(argv[1]); // adjust as needed
/* Process */
/* Output */
cout << n << "\n";
return 0;
}
Note on ios_base::sync_with_stdio(false): This speed optimisation is useful when mixing cin/cout with scanf/printf (which you should not do). For programs using only cout, it provides a minor speedup. Leave it in as standard competitive programming practice.
Practice Problem Set: 10 Challenge Problems
Work through each of these under timed conditions (25 minutes each). These represent the range of problems you will encounter in TCS NQT Foundation and Ninja coding sections.
Challenge 1: Accept N integers as command line arguments. Print the sum of squares of even numbers and the sum of squares of odd numbers separately.
Challenge 2: Accept a string. Print the string with every word reversed individually, but the word order preserved. Example: “hello world” → “olleh dlrow”.
Challenge 3: Accept two arrays (size M and N, all sizes and elements as command line arguments). Merge them into a single sorted array without using any sort function - only the merge step from merge sort.
Challenge 4: Accept N and check if N is a perfect square. If yes, print its square root. If not, print “Not a perfect square”. Do not use sqrt().
Challenge 5: Accept a string. Print all non-repeating characters in the order they appear in the string.
Challenge 6: Accept an array of N integers. Find the maximum sum subarray and print both the sum and the starting and ending indices.
Challenge 7: Accept a positive integer N. Print all prime factors of N in ascending order (with repetition). Example: 12 → 2 2 3.
Challenge 8: Accept a string. Check if it is an anagram of its own reverse. (This is always true - think about it and explain why.)
Challenge 9: Accept N integers. Partition them into two groups: elements at even indices and elements at odd indices. Print each group sorted in ascending order.
Challenge 10: Accept a number. Print the next prime number greater than or equal to that number.
These problems cover the full range of Foundation coding skills. Solving all 10 correctly from scratch, with command line input handling, in under 25 minutes each, means you are fully prepared for the TCS NQT Ninja Coding section.
The Language Decision: When to Switch Mid-Preparation
Many candidates ask: “I’ve been practising in Python, should I switch to C/C++ for TCS?”
The answer depends on where you are in your preparation:
If you have 3+ weeks: Learning C/C++ input/output patterns is feasible and worth doing. The efficiency of C++ STL makes many problems cleaner to solve.
If you have 1-2 weeks: Stick with what you know. A correct Python solution beats an incomplete C++ solution. Spend time on problem-solving, not language switching.
The specific case for C/C++: If your primary language is Java or Python, the command line argument pattern (argc/argv/atoi) requires the same learning investment regardless of which of C/C++ you choose. The 3 programs in Part 1 of this guide cover that learning in under 2 hours of focused practice.
The practical recommendation: Know at least one of C or C++ well enough to handle command line input. Then solve problems primarily in your preferred language. The language does not determine your Foundation coding score - solving the problem correctly does.
C and C++ provide one genuine advantage: speed. If the TCS iON judge times out your Python or Java solution on a large test case, C/C++ will pass. For Foundation-level problems, this rarely matters. For Digital-level competitive problems, it can be the difference between full marks and partial marks.
Part 10: String Programs Extended
Problem ES-1: String Without Using String Library Functions
TCS sometimes tests whether you can work with strings at the character level, without relying on strlen, strcpy, or similar functions.
Implement strlen manually:
int myStrlen(char *s) {
int count = 0;
while (s[count] != '\0') count++;
return count;
}
Implement strcmp manually:
int myStrcmp(char *s1, char *s2) {
int i = 0;
while (s1[i] != '\0' && s2[i] != '\0') {
if (s1[i] != s2[i]) return s1[i] - s2[i];
i++;
}
return s1[i] - s2[i]; // 0 if both ended, positive/negative if one ended first
}
Implement strcpy manually:
void myStrcpy(char *dest, char *src) {
int i = 0;
while (src[i] != '\0') {
dest[i] = src[i];
i++;
}
dest[i] = '\0'; // null-terminate the destination
}
Problem ES-2: Count Words in a String
Problem statement: Count the number of words in a sentence (words separated by single spaces).
C Solution:
#include <stdio.h>
#include <ctype.h>
int main(int argc, char *argv[]) {
char *s = argv[1];
int wordCount = 0;
int inWord = 0;
for (int i = 0; s[i] != '\0'; i++) {
if (!isspace(s[i]) && !inWord) {
wordCount++;
inWord = 1;
} else if (isspace(s[i])) {
inWord = 0;
}
}
printf("%d\n", wordCount);
return 0;
}
C++ Solution:
#include <iostream>
#include <sstream>
#include <string>
using namespace std;
int main(int argc, char *argv[]) {
string s = argv[1];
istringstream iss(s);
string word;
int count = 0;
while (iss >> word) count++;
cout << count << "\n";
return 0;
}
Note on the C++ approach: istringstream with >> automatically handles multiple spaces and trims leading/trailing whitespace.
Problem ES-3: Check if Two Strings Are Anagrams
Problem statement: Two strings are anagrams if they contain the same characters with the same frequencies.
C Solution:
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
int main(int argc, char *argv[]) {
char *s1 = argv[1];
char *s2 = argv[2];
int freq[256] = {0};
// Increment for s1
for (int i = 0; s1[i] != '\0'; i++) freq[(unsigned char)s1[i]]++;
// Decrement for s2
for (int i = 0; s2[i] != '\0'; i++) freq[(unsigned char)s2[i]]--;
// If any frequency is non-zero, not anagrams
for (int i = 0; i < 256; i++) {
if (freq[i] != 0) {
printf("Not Anagram\n");
return 0;
}
}
printf("Anagram\n");
return 0;
}
C++ Solution:
#include <iostream>
#include <algorithm>
#include <string>
using namespace std;
int main(int argc, char *argv[]) {
string s1 = argv[1], s2 = argv[2];
sort(s1.begin(), s1.end());
sort(s2.begin(), s2.end());
cout << (s1 == s2 ? "Anagram" : "Not Anagram") << "\n";
return 0;
}
Two approaches: The C solution uses O(1) space (fixed-size frequency array) and O(N) time. The C++ sort solution uses O(N log N) time but is simpler to write.
Part 11: Advanced Data Structure Programs
Problem ADS-1: Implement a Stack in C
Problem statement: Implement push, pop, and peek operations for a stack. Process a sequence of operations.
C Solution (array-based stack):
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#define MAX_SIZE 100
int stack[MAX_SIZE];
int top = -1;
int isEmpty() { return top == -1; }
int isFull() { return top == MAX_SIZE - 1; }
void push(int val) {
if (isFull()) { printf("Stack overflow\n"); return; }
stack[++top] = val;
}
int pop() {
if (isEmpty()) { printf("Stack underflow\n"); return -1; }
return stack[top--];
}
int peek() {
if (isEmpty()) { printf("Stack empty\n"); return -1; }
return stack[top];
}
int main(int argc, char *argv[]) {
// Process operations from command line:
// argv[1] = operation (push/pop/peek), argv[2] = value if push
for (int i = 1; i < argc; ) {
if (strcmp(argv[i], "push") == 0 && i + 1 < argc) {
push(atoi(argv[i + 1]));
i += 2;
} else if (strcmp(argv[i], "pop") == 0) {
printf("%d\n", pop());
i++;
} else if (strcmp(argv[i], "peek") == 0) {
printf("%d\n", peek());
i++;
} else {
i++;
}
}
return 0;
}
Problem ADS-2: Queue Using Circular Array
C Solution:
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#define MAX_SIZE 100
int queue[MAX_SIZE];
int front = 0, rear = 0, count = 0;
void enqueue(int val) {
if (count == MAX_SIZE) { printf("Queue full\n"); return; }
queue[rear] = val;
rear = (rear + 1) % MAX_SIZE;
count++;
}
int dequeue() {
if (count == 0) { printf("Queue empty\n"); return -1; }
int val = queue[front];
front = (front + 1) % MAX_SIZE;
count--;
return val;
}
int main(int argc, char *argv[]) {
for (int i = 1; i < argc; ) {
if (strcmp(argv[i], "enqueue") == 0 && i + 1 < argc) {
enqueue(atoi(argv[i + 1]));
i += 2;
} else if (strcmp(argv[i], "dequeue") == 0) {
printf("%d\n", dequeue());
i++;
} else { i++; }
}
return 0;
}
Problem ADS-3: Linked List Operations
Problem statement: Build a singly linked list from N values, then print the list in reverse order without reversing the list itself (use recursion).
C Solution:
#include <stdio.h>
#include <stdlib.h>
struct Node {
int data;
struct Node *next;
};
struct Node *createNode(int val) {
struct Node *node = (struct Node *)malloc(sizeof(struct Node));
node->data = val;
node->next = NULL;
return node;
}
void printReverse(struct Node *head) {
if (head == NULL) return;
printReverse(head->next); // recurse to end first
printf("%d", head->data);
if (head->next != NULL) printf(" "); // avoid trailing space at start
}
int main(int argc, char *argv[]) {
struct Node *head = NULL, *tail = NULL;
int n = argc - 1;
for (int i = 1; i < argc; i++) {
struct Node *node = createNode(atoi(argv[i]));
if (head == NULL) { head = tail = node; }
else { tail->next = node; tail = node; }
}
printReverse(head);
printf("\n");
// Free memory (good practice)
struct Node *curr = head;
while (curr) {
struct Node *next = curr->next;
free(curr);
curr = next;
}
return 0;
}
Part 12: Bit Manipulation Programs
Problem BM-1: Check if N is a Power of 2
C Solution:
#include <stdio.h>
#include <stdlib.h>
int isPowerOfTwo(int n) {
if (n <= 0) return 0;
return (n & (n - 1)) == 0;
}
int main(int argc, char *argv[]) {
int n = atoi(argv[1]);
printf("%s\n", isPowerOfTwo(n) ? "Power of 2" : "Not Power of 2");
return 0;
}
Why this works: Powers of 2 in binary are 1, 10, 100, 1000, etc. (exactly one 1-bit). Subtracting 1 from a power of 2 gives 0, 01, 011, 0111 (all the lower bits become 1). AND-ing N with N-1 for a power of 2 gives 0; for any non-power it gives a non-zero result.
Problem BM-2: Swap Two Numbers Without Temporary Variable
C Solution (using XOR):
#include <stdio.h>
#include <stdlib.h>
int main(int argc, char *argv[]) {
int a = atoi(argv[1]);
int b = atoi(argv[2]);
printf("Before: a=%d b=%d\n", a, b);
// XOR swap
a ^= b; // a = a XOR b
b ^= a; // b = b XOR (a XOR b) = a
a ^= b; // a = (a XOR b) XOR a = b
printf("After: a=%d b=%d\n", a, b);
return 0;
}
C solution (using arithmetic):
a = a + b;
b = a - b; // b = (a+b) - b = a
a = a - b; // a = (a+b) - a = b
Note: The XOR method has one pitfall: if a and b point to the same memory location, XOR swap incorrectly sets both to 0. The arithmetic method avoids this but can overflow for large values. In practice, always use a temporary variable in production code - these techniques are exam curiosities.
Additional C vs C++ Comparison: When C Wins
Despite C++ being the recommended language for most TCS problems, C has specific advantages worth knowing:
C is simpler for character-level string work. Manipulating char * arrays with pointer arithmetic is faster to write for experienced C programmers than managing std::string objects for some specific patterns.
C is more explicit about memory. For problems where you need to understand exactly what is happening (memory addresses, pointer arithmetic, struct layouts), C forces clarity that C++ can obscure with abstractions.
C is what is taught in most Indian engineering curricula. If you learned programming in C and are more fluent in it than C++, use C for TCS. A correct, clean C solution beats a buggy C++ solution.
When C clearly loses:
- Sorting: C requires writing or calling
qsortwith a comparator; C++ hasstd::sortwhich is cleaner. - Collections: C has no built-in hash map or dynamic array; C++ STL provides them.
- String operations: C++
std::stringhasfind,substr,replacebuilt in; C requires manual loops or careful library use.
The practical guidance: if you know both at similar levels, C++ is more efficient for problem-solving. If you are stronger in C, the core command line programming and logic patterns in this guide are fully expressible in C.
The Output Validation Mindset
The single biggest source of wrong answers in TCS coding, given correct logic, is output format mismatch. This is fully preventable with one habit: before submitting, compare your output to the sample output character by character.
The checklist:
- Is your output on the same number of lines as the expected output?
- Are numbers separated by exactly the spacing shown (space, comma, newline)?
- Are there any leading or trailing spaces you didn’t intend?
- If the output is a single number, is it on its own line (
\nat the end)? - If the output is “Yes”/”No” or “True”/”False”, does the capitalisation match exactly?
A practical technique: Print your output to a file and use diff locally against the expected output file. diff actual.txt expected.txt shows any differences including invisible characters. In a TCS exam context, this is done mentally by tracing through your code’s print statements.
The extra 60 seconds spent verifying output format is among the highest-return time investments in any coding exam. Logic errors require redesign; format errors require a single character change.
Mastering C and C++ input/output specifically for TCS, through the programs in this guide, means arriving at the TCS coding section with zero uncertainty about the mechanical aspects of submission. The only challenge remaining is the algorithm itself.
Complete Problem Category Summary with Complexity Reference
| Problem | C Approach | C++ Approach | Time Complexity |
|---|---|---|---|
| Sum of N numbers | atoi loop | atoi + vector | O(N) |
| Prime check | sqrt(n) loop | sqrt(n) loop | O(sqrt N) |
| All primes to N | Sieve with calloc | Sieve with vector |
O(N log log N) |
| Palindrome number | Reverse by digits | Same or string compare | O(log N) |
| Palindrome string | Two-pointer | Two-pointer or reverse | O(N) |
| Fibonacci N terms | Two-variable loop | Same | O(N) |
| Armstrong check | Count digits, sum powers | Same | O(log N) |
| Factorial | Iterative product | Same | O(N) |
| Sort array | qsort() | std::sort | O(N log N) |
| Array max/min | Linear scan | max/min_element | O(N) |
| Array rotation | Reversal algorithm | std::rotate | O(N) |
| String reversal | In-place swap | std::reverse or rbegin | O(N) |
| Char frequency | freq[256] array | map<char,int> | O(N) |
| Anagram check | Frequency difference | Sort both, compare | O(N) or O(N log N) |
| GCD | Euclidean algorithm | __gcd() | O(log(min(a,b))) |
| Binary conversion | Extract bit by bit | bitset or manual | O(log N) |
| Power | Binary exponentiation | Same | O(log exp) |
| Perfect number | Sum divisors up to sqrt | Same | O(sqrt N) |
| Count set bits | Loop or __builtin_popcount | __builtin_popcount | O(log N) or O(1) |
| Second largest | Single pass | Sort descending | O(N) |
Frequently Asked Questions: C/C++ on TCS Platform
“Should I include #include <bits/stdc++.h> or individual headers?”
For C++, #include <bits/stdc++.h> is the competitive programmer’s convention and is supported on TCS iON (GCC compiler). It includes everything. For C, there is no equivalent - you must include individual headers. If you are writing C, include only what you use: stdio.h, stdlib.h, string.h, math.h as needed.
“What data type should I use for large numbers?”
For counts, indices, and most intermediate values: int (up to ~2.1 billion).
For sums that might overflow int: long long (up to ~9.2 × 10^18).
For products that might overflow long long: use intermediate modular arithmetic ((a * b) % MOD at each step) or Python.
For very large numbers (> 10^18): no native type in C/C++ - use strings or Python.
“Can I use global variables in TCS coding?” Yes. Global variables are perfectly acceptable. For programs with multiple helper functions, global arrays can simplify data passing. This is a common competitive programming practice.
“The problem says ‘print without newline at the end’. How do I do that?”
Simply omit the \n at the end of your last printf/cout statement. The line printf("%d", result); prints the integer with no newline.
“Can I use multiple source files?”
TCS iON is a single-file submission environment. All code must be in one file. Functions, structs, and global variables all go in the same .c or .cpp file.
“What happens if my program takes too long?” The judge will return a TLE (Time Limit Exceeded) verdict. The test case is scored as incorrect. Partial credit for other test cases that completed within the time limit is still awarded. If TLE affects only large test cases, your logic is correct but your algorithm is too slow - submit the current solution for partial credit, then optimise.
“My code compiles locally but gets a compilation error on TCS iON. Why?” Common causes:
- You used a C++-specific feature in a file submitted as C (e.g.,
//comments in older C89 mode) - You used a non-standard extension that GCC accepts but the TCS compiler version rejects
- Missing header (something included transitively by
bits/stdc++.hlocally but not on the platform)
Fix: Add explicit #include for every header you use. Avoid compiler-specific extensions that are not in the C99/C11 or C++14 standards.
“How do I read a string with spaces using command line arguments?”
Pass the string in quotes at the shell level: ./program "hello world". Inside the program, argv[1] will be "hello world" as a single string. The shell processes the quotes and passes everything within them as one argument.
The atoi Edge Cases: What Every TCS Candidate Should Know
atoi is simple but has specific behaviour at edge cases that can cause bugs:
atoi("0") returns 0 - correct.
atoi("-5") returns -5 - handles negative correctly.
atoi(" 42 ") returns 42 - skips leading whitespace.
atoi("42abc") returns 42 - stops at first non-digit.
atoi("abc") returns 0 - no digits found, returns 0.
atoi("9999999999") is undefined behaviour - value exceeds int range. Use atol() (returns long) or strtol() (returns long with error checking) for large numbers.
The safe alternative for large numbers:
long long val = strtoll(argv[1], NULL, 10);
strtoll converts to long long and the 10 specifies base 10. This handles numbers up to ~9.2 × 10^18 correctly.
The full version with error checking:
char *endptr;
long long val = strtoll(argv[1], &endptr, 10);
if (*endptr != '\0') {
printf("Invalid number: %s\n", argv[1]);
return 1;
}
endptr points to the first character that was not part of the number. If it is '\0', the entire string was a valid number.
Connecting C/C++ Practice to the Broader TCS Preparation
The command line argument pattern (argc, argv, atoi) is specific to TCS’s coding environment. Every other aspect of C/C++ programming - the logic, the algorithms, the data structures - is universal across competitive programming platforms.
This means your practice on external platforms (LeetCode, HackerRank, CodeChef) using C++ is fully transferable to TCS. The only adaptation needed is replacing cin input with atoi(argv[N]) input. A candidate who has solved 50 problems on HackerRank using C++ needs only 2-3 hours of practice with the command line pattern to be fully prepared for TCS’s input format.
Conversely, if you have practised all the programs in this guide with command line input but not practised general algorithmic problem-solving, you will handle the input correctly but struggle with harder problems. Both aspects - the TCS-specific input format and the general algorithmic preparation - are necessary.
The programs in this guide cover the TCS NQT Foundation and Ninja coding range completely. The Digital Advanced coding articles in this series cover the algorithms needed for Digital-level problems. Together, they provide the complete C/C++ preparation framework for TCS coding at every level.