Thread: C implementation of linux command

  1. #1
    Registered User
    Join Date
    Apr 2020
    Posts
    2

    C implementation of linux command

    I have the following code which simulate the functionality of the wc command in linux. The problem I have is with the lines alignment.
    Code:
    Example:
    ./wcfile wcfile.c
      78  226 1693 wcfile.c
    The number of spaces is aligned after the longest number. In that example 1693 have 4 digits and 78 have only 2, so the program will insert 2 more spaces. The formula is number of digits from lines(total number of lines(78 here)) + number of spaces before the wnumber of lines should be equal to the number of bytes.
    The number of digits from words(226 here) + the number of spaces before the number of words should be equal to the number of digits from bytes +1(because the of the space between no. of words and no. of bytes). So 226 have 3 digits + 2 spaces should be equal to the number of digits that bytes have(4)+1 which is 5. The program works fine if I put only one line, but for multiple lines wc command in linux display the spaces after the last line witch is the total line.
    Code:
    Example:
    diff <(./wcfile wcfile Makefile wcfile2 ceva ceva2) <(wc wcfile Makefile wcfile2 ceva ceva2)
    1,6c1,6
    <    10   144 12632 wcfile 
    <    22    60 465 Makefile
    <    20   136 8536 wcfile2
    <    12   149 12640 ceva
    <    11   151 12632 ceva2
    <    75   640 46905 total 
    ---
    >    10   123 12632 wcfile 
    >    22    60   465 Makefile
    >    20   106  8536 wcfile2
    >    12   116 12640 ceva
    >    11   112 12632 ceva2
    >    75   517 46905 total
    Here the umber of spaces depends of the last total line. The no. of spaces of the total is calculated with the same formula as above. But the last above the total lines will be displayed after the total line and the numbers will be displayed from right to left.(line 2, the number 465 from the example above). I tried printing with %5d or so but this won't help because the number of spaces is unknown from the beginning. You can know the number only after you run the code and get the total number of bytes from the last/total line.
    The code that I am using is the following:

    Code:
    #include <stdio.h>
    #include <string.h>
    #include <unistd.h>
    #include <fcntl.h>
    #include <sys/types.h>
    
    #define LUNG_BUF 4096
    
    int main(int argc, char** argv)
    {
      int bytes = 0;
      int words = 0;
      int newLine = 0;
      int max_value;  // the maximum of the above three
      int dim;        // string width of the max value
    
      char buffer[LUNG_BUF];
      enum states { WHITESPACE, WORD };
      int state = WHITESPACE;
      if ( argc !=2 )
      {
        printf( "Nu ati introdu snumele  fisierului\n%s", argv[0]);
      }
      else
      {
        int file = open(argv[1], O_RDONLY);
    
        if(file < 0)
        {
          printf("can not open :%s\n",argv[1]);
        }
        else
        {
          char *thefile = argv[1];
          size_t n;
    
          while ((n = read(file, buffer, LUNG_BUF - 1)) > 0)
          {
            buffer[n] = '\0';
            char *ptr = buffer;
    
            while (*ptr)
            {
              bytes++;
              if (*ptr == ' ' || *ptr == '\t')
              {
                state = WHITESPACE;
              }
              else if (*ptr == '\n')
              {
                newLine++;
                state = WHITESPACE;
              }
              else
              {
                if (state == WHITESPACE)
                {
                    words++;
                }
                state = WORD;
              }
              ptr++;
            }
          }
    
          // find out the largest value of all and determine the printed width of it
          max_value = newLine;
          if (words > max_value)
            max_value = words;
          if (bytes > max_value)
            max_value = bytes;
          dim = snprintf(NULL, 0, "%d", max_value);
    
          // print lines, words, bytes and filename aligned to the longest number
          printf("%*d %*d %*d %s\n", dim, newLine, dim, words, dim, bytes, thefile);
        }
      }
    }
    The code for multiple lines which calculate calculate and display the total line
    Code:
    #include <stdio.h>
    #include <string.h>
    #include <unistd.h>
    #include <ctype.h>
    int main(int argc, char* argv[])
    {
        int sumL=0,sumW=0,sumB=0,index=0;
        int buffer=0;
        enum states { WHITESPACE, WORD };
    
        if ( argc==1 )
        {
            printf( "Nu ati introdu snumele  fisierului\n%s", argv[0]);
        }
        else
        {
            while(--argc>0)
            {
                int bytes = 0;
                int words = 0;
                int newLine = 0;
                int state = WHITESPACE;
                FILE *file = fopen( *++argv, "r");
    
                if(file == 0)
                {
                    printf("can not find :%s\n",argv[1]);
                }
                else
                {
                    char *thefile = *argv;
    
                    while (EOF != (buffer = fgetc (file)))
                    {
                        bytes++;
                        if ( isspace ( (unsigned char) buffer))
                        {
                            state = WHITESPACE;
                            if (buffer=='\n')
                            {
                                newLine++;
                            }
                        }
                        else
                        {
                            if ( state == WHITESPACE )
                            {
                                if (isgraph ( ( unsigned char) buffer))
                                {
                                    words++;
                                    state = WORD;
                                }
                            }
                        }
    
                    }
                    printf(" %d %d %d %s\n",newLine,words,bytes,thefile);
                    sumL+=newLine;
                    sumW+=words;
                    sumB+=bytes;
                    index++;
                }
            }
            if(index>1)
                printf(" %d %d %d total \n",sumL,sumW,sumB);
        }
        return 0;
    }

  2. #2
    and the hat of int overfl Salem's Avatar
    Join Date
    Aug 2001
    Location
    The edge of the known universe
    Posts
    38,165
    Actual 'wc' starts by doing a stat on each file to get the size of the file, and uses the largest file size calculate a 'guess' for the field widths.
    stat(2): file status - Linux man page
    If you dance barefoot on the broken glass of undefined behaviour, you've got to expect the occasional cut.
    If at first you don't succeed, try writing your phone number on the exam paper.

Popular pages Recent additions subscribe to a feed

Similar Threads

  1. Linux cp command C implementation
    By Kimeru in forum C Programming
    Replies: 1
    Last Post: 05-20-2017, 11:12 PM
  2. Implementation of linux cp (copy) command in C language
    By eurosickwitit in forum C Programming
    Replies: 3
    Last Post: 11-17-2011, 10:40 AM
  3. Ketchup command in linux?
    By kiros88 in forum Tech Board
    Replies: 4
    Last Post: 04-21-2010, 11:56 AM
  4. C implementation of unix ls command
    By sinkovich in forum Linux Programming
    Replies: 0
    Last Post: 02-24-2003, 04:38 AM
  5. cd command in linux console
    By TheUnheardHuman in forum Tech Board
    Replies: 2
    Last Post: 11-19-2002, 03:59 PM

Tags for this Thread