-2

I have implemented my own dynamic-memory version of getline function:

char * fgetline(FILE * f)

Starts with 30 character buffer and when the buffer is full allocate a new one copy the contents and free the old buffer. When we get EOF or \n we return from the function.

I want to use this function to implement a version of the program tail. Input comes from stdin, output goes to stdout. If the first argument begins with -, everything after the - is the number of lines to print. The default number of lines to print is 10, when no argument is given.

I have thought until now that I should use the function:

int atoi (const char *s) 

from stdlib.h and have an array of pointers to lines but I don't know exactly how to do this.

Any ideas?

stefan
  • 10,215
  • 4
  • 49
  • 90
kokosg
  • 123
  • 3
  • 11
  • 2
    If your question is how you should handle command line parameters I'd suggest you have a look at [getopt](http://linux.die.net/man/3/getopt) because that's a flexible way of accepting parameters. – fvu Oct 27 '12 at 12:37
  • If you call with `./myTail -20 somefile`, then you'll get the argument as `char*`. To ignore the dash, just increment the pointer (in this case argv[1]) by 1 before feeding into `atoi`. – stefan Oct 27 '12 at 12:39
  • @fvu no I know how to. My question is how to do this? Should I read the whole text and have an array of pointers to each line and then print only the last N where N is from the parameter? I want more help how to do this or if there is an easier way. – kokosg Oct 27 '12 at 12:42
  • @stefan I know how to do this. I just want to implement such a program as tail. – kokosg Oct 27 '12 at 12:43
  • Well then the absolutely simplest and wisest thing to do would be to [consult](http://www.raspberryginger.com/jbailey/minix/html/tail_8c-source.html) any of the [many](http://swtch.com/usr/local/plan9/src/cmd/tail.c) sources available - see http://stackoverflow.com/questions/1439799/how-can-i-get-the-source-code-for-the-linux-utility-tail as well. – fvu Oct 27 '12 at 14:15
  • @kokosg What's your _specific_ problem? If you know what you want and know how to parse command line arguments and how to parse files, why not just implement it? – stefan Oct 27 '12 at 14:27
  • @stefan I don't need file handling. Input of the file comes from stdin. I don't know how to read the text and save pointers in array that point to each line. – kokosg Oct 27 '12 at 15:12

1 Answers1

1

Declare your main function as

 int main (int argc, char**argv) {
 }

If you compile your program to myprog executable, and invoke it as myprog -20 somefile anotherfile then you have:

argc == 4 
&& strcmp(argv[0], "myprog") == 0
&& strcmp(argv[1], "-20") == 0
&& strcmp(argv[2], "somefile") == 0
&& strcmp(argv[3], "anotherfile") == 0
&& argv[4] == NULL

in other words, you might want to have your program containing

int nblines = 10;

int main(int argc, char**argv) {
  int argix = 1;
  if (argc>1) {
    if (argv[1][0]=='-') 
      { 
         nblines = atoi(argv[1]+1);
         argix = 2;
      }
     for (; argix < argc; argix++)
        tail (argv[argix]);
  }
  return 0;
}

It is up to you to implement your void tail(char*filename); function appropriately. Don't forget to compile with all warnings & debugging info, e.g. with gcc -Wall -g on Linux. Use your debugger (gdb on Linux) to debug your program. Take into account that fopen can fail, and use errno to display an appropriate error message.

Notice that you don't need your fgetline function. The getline(3) function is standard (in Posix 2008) and is dynamically allocating the line buffer.

Basile Starynkevitch
  • 223,805
  • 18
  • 296
  • 547
  • thank you for your answer but as I said before input comes from stdin, output goes to stdout. No need of file handling. The real question is how to do the tail function work with my already implemented fgeltine function who reads from stdin as described. – kokosg Oct 27 '12 at 13:24
  • can you give me any hint on how to do the tail function? – kokosg Oct 27 '12 at 15:51
  • 1
    Use `calloc` to dynamically allocate an array of `nblines` string pointers. Then fill that array in round-robin fashion with each line obtained by `getline` (or maybe your `fgetline`, which I feel is useless, since `getline` does the job). At the end of file, output that dynamically allocated array (starting appropriately at the current line and wrapping). For elegance, don't forget to `free` all the dynamically allocated data before `exit`-ing. – Basile Starynkevitch Oct 27 '12 at 16:00
  • How I am supposed to fill the array of pointers? When fgetline reaches \n returns. So how I can read the whole input text with lines? I would be grateful if you show me a code sample for doing what you described because I am very confused. Otherwise, thank you so much for your time. – kokosg Oct 27 '12 at 16:19
  • 1
    Please try to do by yourself your homework, or simply get the source code of the free software (GPL licensed) `tail` utility and study its source code on http://git.savannah.gnu.org/cgit/coreutils.git/tree/src/tail.c – Basile Starynkevitch Oct 27 '12 at 16:22