C выравнивание линий как в команде linux - PullRequest
0 голосов
/ 25 апреля 2020

У меня есть следующий код, который имитирует функциональность команды w c в linux. У меня проблема с выравниванием линий.

Example:
./wcfile wcfile.c
  78  226 1693 wcfile.c

Количество пробелов выравнивается после самого длинного числа. В этом примере 1693 имеют 4 цифры, а 78 - только 2, поэтому программа вставит еще 2 пробела. Формула представляет собой количество цифр из строк (общее количество строк (78 здесь)) + количество пробелов до того, как количество строк должно быть равно количеству байтов. Количество цифр в словах (226 здесь) + количество пробелов перед количеством слов должно быть равно количеству цифр в байтах +1 (из-за пробела между числом слов и числом байтов). Таким образом, 226 имеют 3 цифры + 2 пробела должны быть равны количеству цифр, которые байты имеют (4) +1, что равно 5. Программа работает нормально, если я поставил только одну строку, но для нескольких строк w c команда в linux отображает пробелы после последней строки с итоговой строкой.

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

Здесь количество пробелов зависит от последней итоговой строки. Нет. Пространств от суммы рассчитывается по той же формуле, что и выше. Но последние над строками итогов будут отображаться после итоговых строк, а цифры будут отображаться справа налево (строка 2, число 465 из приведенного выше примера). Я пробовал печатать с% 5d или около того, но это не поможет, потому что количество пробелов неизвестно с самого начала. Вы можете узнать число только после того, как запустите код и получите общее количество байтов из последней / итоговой строки. Код, который я использую, следующий:

#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);
    }
  }
}

Код для нескольких строк, которые вычисляют, вычисляют и отображают итоговую строку

#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;
}
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...