Building Linux Commands From Scratch 🐧 cat Command — Adding New Features
Tags: linux, programming, c, cli
Published: 2024-03-17 09:59:08

In the last post i wrote the basic cat command in C that could prints the content of the files to the standard output. Now it is time to update it, adding two features.

- Using the program as cat without any command line arguments
- Using **-n** option to print line numbers


![Adding New Features](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/0kusoqmvdb6misjakjjz.png)

---

For the first part, these are the changes made to original program (Please read the previous blog).

```c
#define MAX 1000
```

```c
int main(int argc, char *argv[])
{
  char input[MAX];
```

```c
  else
  {
    while (1)
    {
      scanf("%s", input);
      printf("%s\n", input);
    }
  }
```

Here the input is an array of type **char**. If the _argc_ is 0 then it comes under **else** block and then to the **while** loop, where for each iteration the input is read from standard input and prints it to standard output.


![Loop, Scan And Print](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/2n7tyyiilp5g54y3njym.png)

For the second part, a new function is created **_printFile()_**.

```c
#define TRUE 1
#define FALSE 0

void printFile(char *argv[], int argc, int index, int numbers)
{
  char character;
  int count = 0;

  for (int i = index; i < argc; i++)
  {
    FILE *file = fopen(argv[i], "r");

    if (numbers)
      printf("\t%d ", ++count);
    while ((character = fgetc(file)) != EOF)
    {
      printf("%c", character);
      if (numbers && character == '\n')
        printf("\t%d ", ++count);
    }

    fclose(file);
  }
}
```

Here the signature of the function is,

```c
void printFile(char *argv[], int argc, int index, int numbers);
```

Here the index is from where the loop starts, and numbers takes value of 1 and 0, if it is 1 it prints the numbers or else it doesn’t.

```c
if (argc > 1)
{
   if (strcmp(argv[1], "-n") == 0)
   {
      printFile(argv, argc, 2, TRUE);
   }
   else
   {
      printFile(argv, argc, 1, FALSE);
   }
}
```

Here checking if first argument is “**_-n_**”, if it is then calling **_printFile()_** with _argv, argc, index = 2, and numbers = TRUE_ or else it is calling **_printFile()_** with _argv, argc, index = 1, and numbers = FALSE_.

```c
#include <stdio.h>
#include <string.h>

#define MAX 1000
#define TRUE 1
#define FALSE 0

void printFile(char *argv[], int argc, int index, int numbers)
{
  char character;
  int count = 0;

  for (int i = index; i < argc; i++)
  {
    FILE *file = fopen(argv[i], "r");

    if (numbers)
      printf("\t%d ", ++count);
    while ((character = fgetc(file)) != EOF)
    {
      printf("%c", character);
      if (numbers && character == '\n')
        printf("\t%d ", ++count);
    }

    fclose(file);
  }
}

int main(int argc, char *argv[])
{
  char input[MAX];

  if (argc > 1)
  {
    if (strcmp(argv[1], "-n") == 0)
    {
      printFile(argv, argc, 2, TRUE);
    }
    else
    {
      printFile(argv, argc, 1, FALSE);
    }
  }
  else
  {
    while (1)
    {
      scanf("%s", input);
      printf("%s\n", input);
    }
  }

  return 0;
}
```

Checkout the repository at [GitHub](https://github.com/surajkareppagol/Linux-Commands).

{% embed https://youtu.be/eV_2SD831g4 %}