0

The following is a part of my program trying to implement 'squeeze' or '-s' of 'cat' command using c. Now the main function uses argv and argc, which are analysed by using getopt function.'squeeze' function is called in main and 'stdin' and 'stdout' are passed as arguments. also the return type of getopt function is passed in writeLineNumbers. I am just wondering if this is the right way to do it?

void squeeze ( FILE *fin, FILE *fout, int writeLineNumbers)
{
    char line[len];
    //int linenumber=1;

    while (fgets(line,len,fin))
    {
        if(line==NULL)
            fin--=fin;
        if (fputs(line, fout)==EOF)
        {
            printf(stderr,"Write to stdout failed.");
            return;
        }
       // ++linenumber;
    }

}
Ryan T. Grimm
  • 1,307
  • 1
  • 9
  • 17
  • 2
    You are misusing the `printf` function. According to the man, its first argument is a `const char *`. To write to a file descriptor (like `stderr`) using a function from the `printf` family, you should use `dprintf`. – Aliou Mar 28 '14 at 15:36
  • 3
    `line==NULL` is always `false`, `fgets` doesn't modify `line`. And what is `fin--=fin` supposed to mean ? – Jabberwocky Mar 28 '14 at 15:37
  • isn't fgets supposed to copy stuff from fin to line? – user3446270 Mar 28 '14 at 15:39
  • Do not you want `else if (fputs(line, fout)==EOF)`? – chux - Reinstate Monica Mar 28 '14 at 15:41
  • @user3446270: yes it is, `fgets` will modify the **content** of the `line`buffer, but `line` will have the same value all the time, it will never be zero. You want to test if a line is empty, so you must use a test like `if (line[0] == '\n')`. – Jabberwocky Mar 28 '14 at 15:42
  • 4
    The `fin-- = fin;` line is weird (and undefined behaviour). – Jonathan Leffler Mar 28 '14 at 15:44
  • @ chux agreed @Michael agreed – user3446270 Mar 28 '14 at 15:45
  • 2
    The squeeze option basically looks for consecutive sequences of two or more newlines and only emits two newlines when it encounters such a sequence. There's a considerable temptation to write the code in terms of `getc()`, which needn't be all that bad for performance (and correctness is more important than performance). If you use `fgets()`, you have to worry about whether you read the whole line (was the last character in the buffer a newline); otherwise, if your buffer is, say, 256 characters long, and you get to read a line of 255 characters plus newline, you could get a spurious newline. – Jonathan Leffler Mar 28 '14 at 15:58
  • @JonathanLeffler I know, I am trying to figure out how else i can do it. – user3446270 Mar 28 '14 at 15:58
  • @JonathanLeffler should i just check for the first and last character of the line in that case? – user3446270 Mar 28 '14 at 16:01
  • For what it's worth, [GNU `cat`](http://git.savannah.gnu.org/gitweb/?p=coreutils.git;a=blob_plain;f=src/cat.c;hb=HEAD) counts new-lines and `continue`s the loop after the first, if `squeeze_blank` is set. – John C Mar 28 '14 at 18:35
  • @Allou - `stderr` is a `FILE *`, and the relevant function is `fprintf` – M.M Mar 31 '14 at 03:37

1 Answers1

0

Try this :

   void squeeze (FILE *fin, FILE *fout, int writeLineNumbers)
    {
    char line[len] = {0};

    while (fgets(line, len, fin))
    {
        if(strlen(line) != 0)
        {
          if (fputs(line, fout) == EOF)
          {
            printf(stderr,"Write to stdout failed.");
            return;
        }
    }
}
Orelsanpls
  • 22,456
  • 6
  • 42
  • 69
  • 2
    `fgets()` includes the newline, so `strlen(line)` won't be zero (it will be 1, usually). Better would be `line[0] == '\n'`. – Jonathan Leffler Mar 28 '14 at 15:43
  • Do not see the need for `if(strlen(line) != 0)` - not that it hurts. Same with `bzero(line, len);` - why zero the array? – chux - Reinstate Monica Mar 28 '14 at 15:43
  • Yes we need `if(strlen(line) != 1)` (not `!= 0`), it's the whole point of the program. But correct `bzero` isn't needed. – Jabberwocky Mar 28 '14 at 15:46
  • ok well, I am still not sure if this should do it. My confusion is the following: Argv is a string of vectors pointing to addresses of various strings. argc keeps a count of those strings. get opt analyses argv and argc. the third argument taken by get opt is the " double quote" function to implement. now what exactly is returned in 'opt'(refer to my code). and is this the right thing to pass opt as an argument for 'squeeze'. while((opt=getopt(argc, argv, "benstv"))!=-1) switch (opt) { case 's': sflag=1; squeeze(stdin, stdout, opt); break; } – user3446270 Mar 28 '14 at 15:48
  • 1
    @Michael Walz as call to `fgets()` can result in `line` with a `strlen(line)` of 0 (rare circumstances) or 1 (rarely without a `'\n'`), what is the `if(strlen(line) != 1)` trying to accomplish? Maybe what is needed is a call like `IsStringOnlyWhiteSpace(line)`? – chux - Reinstate Monica Mar 28 '14 at 15:55
  • 'squeeze' fuction in cat implies that----> Squeeze multiple adjacent empty lines, causing the output to be single spaced. so, how do i sort of delete the other empty lines by using argv. – user3446270 Mar 28 '14 at 15:56
  • 1
    @user3446270: you seem to be confused about `argv`. Your command line handling detects which file(s) to process, but the code opens each file in turn (unless it needs to read standard input), and then calls a function (`squeeze()` when `-s` is given) to process the file(s). The general structure of `main()` will be: (1) spot the options and set flags; (2) loop over the file names left over, or standard input if there is no file name, processing according to the flags set. – Jonathan Leffler Mar 28 '14 at 16:01
  • @chux: your are right, actually the `if(strlen(line) != 1)` only does approximately what we want, is just to give OP an idea. – Jabberwocky Mar 28 '14 at 16:01
  • @JonathanLeffler okay, so do i just pass stdin as an argument for squeeze function? or should i use another pointer like fin? – user3446270 Mar 28 '14 at 16:08