0

I currently have a shell script in C that takes a command of a file, two numbers, mth line and nth line, and supposedly should output whats in between those lines:

for example:

./output file1 2 6

would output file from line 2 to line 6

I have it implemented currently in a way of outputting the whole file, I have been trying to change it to output specifically between those lines

this is my code

#include <fcntl.h>

int main(int argc, char *argv[])
{
    int file;
    int size;
    int l[1000];

    int firstNum = atoi(argv[2]);

    int secondNum = atoi(argv[3]);


    file = open(argv[1], O_RDONLY);

    if( file == -1)
    {
        printf("\n cannot open file \n");
    }

    while ((size=read(file,l,80)) > 0)
        write(1,l,size);




}

I tried to change l and size to firstNum and secondNum, which are the numbers entered from the command line, but still did not work and outputted one single line.

What is a better way of doing so ?

Barmar
  • 741,623
  • 53
  • 500
  • 612
Mohamad Zein
  • 777
  • 1
  • 8
  • 33
  • "a shell script in C"? – Barmar Feb 04 '16 at 04:48
  • Much the simplest is `char cmd[256]; snprintf(cmd, sizeof(cmd), "sed -n '%s,%sp %s", argv[2], argv[3], argv[1]); system(cmd);`. Run `sed` to print only between the two line numbers passed as arguments on the file specified. – Jonathan Leffler Feb 04 '16 at 04:53

2 Answers2

2

There are several issues with your code, so just go through them sequentially:

  • It's better to use high level fopen rather than low level open to open a file. So it's better to write this way:

    FILE *file = fopen(argv[1], "r");
    if (file == NULL)
        exit(EXIT_FAILURE);
    
  • Your read is wrong as it reads exactly 80 characters instead of a line as you expect.

    while ((size=read(file,l,80)) > 0)   // <-- WRONG because this reads 80 chars instead of one line
    
  • For similar reason as with open, it's better to use alternative like printf instead of low level read and write.

  • To read line by line, you should use library function getline.

  • To control what line number to print, a simple way is to have a variable tracking what line number and compare with your command line arguments.

So put them together, you would need something like this:

FILE *file = fopen(argv[1], "r");
if (file == NULL)
    exit(EXIT_FAILURE);

int line_num = 0;

char * line = NULL;
size_t len = 0;
ssize_t read = 0;
while ((read = getline(&line, &len, file)) != -1)
{
    line_num++;
    if( firstNum <= line_num && line_num <= secondNum )
    {
        printf( "line %d: %s", line_num, line );
        if( line_num == secondNum )
            break;
    }
}
artm
  • 17,291
  • 6
  • 38
  • 54
0

Try looking at this post: C read file line by line

From there it should be a simple matter of counting lines read and discarding them until you have read firstNum lines at which point print until you've reached secondNum.

Community
  • 1
  • 1
Michael Albers
  • 3,721
  • 3
  • 21
  • 32