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