newpoint
asked on
Fix Tail
/*I found this example in one of my book's given to me. The problem with this it will not compile. Could someone show me what the problem is. I guess this is really a two part question. By the looks the of the program is should print out the last ten lines of something. Does this mean it should look at a file, if so could you bump it up so that it could do that. I'm just curious on how this would work.
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#define DEFLINES 10
#define LINES 100
#define MAXLEN 100
void error(char *);
int getline(char *, int);
main(int argc, char *argv[])
{
char *p;
char *buf;
char *bufend;
char line[MAXLEN];
char *lineptr[LINES];
int first, i, last, len, n, nlines;
if (argc == 1)
n = DEFLINES;
else if (argc == 2 && (*++argv)[0] == '-')
n = atoi(argv[0] + 1);
else
error("usage: tail [-n]");
if(n < 1 || n > LINES)
n = LINES;
for (i = 0; i < LINES; i++)
lineptr[i] = NULL;
if((p = buf = malloc(LINES * MAXLEN)) == NULL)
error("tail: cannot allocate buf");
bufend = buf + LINES * MAXLEN;
last = 0;
nlines = 0;
while ((len = getline(line, MAXLEN)) > 0)
{
if(p + len + 1 >= bufend)
p = buf;
lineptr[last] = p;
strcpy(lineptr[last], line);
if(++last >= LINES)
last = 0;
p += len + 1;
nlines++;
}
if (n > nlines)
n = nlines;
first = last - n;
if(first < 0)
first += LINES;
for ( i = first; n --> 0; i = ( i + 1 ) % LINES )
printf("%s", lineptr[i]);
return 0;
}
void error(char *s)
{
printf("%s\n", s);
exit(1);
}
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#define DEFLINES 10
#define LINES 100
#define MAXLEN 100
void error(char *);
int getline(char *, int);
main(int argc, char *argv[])
{
char *p;
char *buf;
char *bufend;
char line[MAXLEN];
char *lineptr[LINES];
int first, i, last, len, n, nlines;
if (argc == 1)
n = DEFLINES;
else if (argc == 2 && (*++argv)[0] == '-')
n = atoi(argv[0] + 1);
else
error("usage: tail [-n]");
if(n < 1 || n > LINES)
n = LINES;
for (i = 0; i < LINES; i++)
lineptr[i] = NULL;
if((p = buf = malloc(LINES * MAXLEN)) == NULL)
error("tail: cannot allocate buf");
bufend = buf + LINES * MAXLEN;
last = 0;
nlines = 0;
while ((len = getline(line, MAXLEN)) > 0)
{
if(p + len + 1 >= bufend)
p = buf;
lineptr[last] = p;
strcpy(lineptr[last], line);
if(++last >= LINES)
last = 0;
p += len + 1;
nlines++;
}
if (n > nlines)
n = nlines;
first = last - n;
if(first < 0)
first += LINES;
for ( i = first; n --> 0; i = ( i + 1 ) % LINES )
printf("%s", lineptr[i]);
return 0;
}
void error(char *s)
{
printf("%s\n", s);
exit(1);
}
Hi newpoint;
1. Adding a (char *) will get rid of the compile error message.
if((p = buf =(char *) malloc(LINES * MAXLEN)) == NULL)
2. It's also missing the function definition for getline(). Is that earlier in the book?
3. Are you aware that this program uses command line arguments? ( e.g. dir /w ) That is where the string is coming from, not a file.
Matt
1. Adding a (char *) will get rid of the compile error message.
if((p = buf =(char *) malloc(LINES * MAXLEN)) == NULL)
2. It's also missing the function definition for getline(). Is that earlier in the book?
3. Are you aware that this program uses command line arguments? ( e.g. dir /w ) That is where the string is coming from, not a file.
Matt
I suspect that "it won't compile" means that the procedure getline is missing.It is declared at the top but it's missing at the bottom (unlike error).
Rat's have tails but what is meant here is the Unix utility command tail which takes an optional parameter, namely a number of lines n, here defaulted to DEFLINES or 10, up to a maximum value (here LINES or 100) and prints out the last n lines from a file. The "print out" is acutally standard output (stdout) and it would very much surprise me that, if we had the source of getline, it wouldnot take them from standard input (stdin). The usage would be (if we had a program called fred which outputs text) :-
fred | tail -23 -- the | means pipe as in water-pipe
which would print out the last 23 lines of fred's output
What's the book incidentally?
Rat's have tails but what is meant here is the Unix utility command tail which takes an optional parameter, namely a number of lines n, here defaulted to DEFLINES or 10, up to a maximum value (here LINES or 100) and prints out the last n lines from a file. The "print out" is acutally standard output (stdout) and it would very much surprise me that, if we had the source of getline, it wouldnot take them from standard input (stdin). The usage would be (if we had a program called fred which outputs text) :-
fred | tail -23 -- the | means pipe as in water-pipe
which would print out the last 23 lines of fred's output
What's the book incidentally?
/* Sorry if this posts twice, but I had trouble with my browser.
I replaced getline with fgets, and eliminated a few other
variables. Also, I changed the way the lines are stored by
the program. I believe it is still readable.
The program will also need a file as an argument
ex: tail test.txt -25
or
tail test.txt
*/
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#define DEFLINES 10
#define LINES 100
#define MAXLEN 100
void error(char *);
main(int argc, char *argv[])
{
FILE *input;
char *buf[LINES];
char line[MAXLEN];
int i, n, nlines;
int last;
if (argc == 2)
{
if ( (input = fopen(argv[1], "r")) == NULL)
error("could not open file");
n = DEFLINES;
}
else if (argc == 3 && argv[2][0] == '-')
{
if ( (input = fopen(argv[1], "r")) == NULL)
error("could not open file");
n = atoi(argv[2] + 1);
}
else
error("usage: tail <filename> [-n]");
if(n < 1 || n > LINES) /* Default to 10 lines in bad input */
n = DEFLINES;
for (i = 0; i < n; ++i)
if((buf[i] = malloc(MAXLEN*sizeof(char) )) == NULL)
error("tail: cannot allocate buf");
nlines = 0;
last = 0;
while ( fgets(line, MAXLEN, input) != NULL )
{
strcpy(buf[last++], line);
if (last == n)
last = 0;
nlines++;
} /* END READING INPUT FILE */
if (n > nlines)
n = nlines;
if (last != 0)
--last;
for ( i = 0; i < n; ++i)
{
printf("%s", buf[last++]);
if (last == n)
last = 0;
}
for (i = 0; i < n; ++i)
free(buf[i]);
fclose(input);
return 0;
}
void error(char *s)
{
printf("%s\n", s);
exit(1);
}
I replaced getline with fgets, and eliminated a few other
variables. Also, I changed the way the lines are stored by
the program. I believe it is still readable.
The program will also need a file as an argument
ex: tail test.txt -25
or
tail test.txt
*/
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#define DEFLINES 10
#define LINES 100
#define MAXLEN 100
void error(char *);
main(int argc, char *argv[])
{
FILE *input;
char *buf[LINES];
char line[MAXLEN];
int i, n, nlines;
int last;
if (argc == 2)
{
if ( (input = fopen(argv[1], "r")) == NULL)
error("could not open file");
n = DEFLINES;
}
else if (argc == 3 && argv[2][0] == '-')
{
if ( (input = fopen(argv[1], "r")) == NULL)
error("could not open file");
n = atoi(argv[2] + 1);
}
else
error("usage: tail <filename> [-n]");
if(n < 1 || n > LINES) /* Default to 10 lines in bad input */
n = DEFLINES;
for (i = 0; i < n; ++i)
if((buf[i] = malloc(MAXLEN*sizeof(char)
error("tail: cannot allocate buf");
nlines = 0;
last = 0;
while ( fgets(line, MAXLEN, input) != NULL )
{
strcpy(buf[last++], line);
if (last == n)
last = 0;
nlines++;
} /* END READING INPUT FILE */
if (n > nlines)
n = nlines;
if (last != 0)
--last;
for ( i = 0; i < n; ++i)
{
printf("%s", buf[last++]);
if (last == n)
last = 0;
}
for (i = 0; i < n; ++i)
free(buf[i]);
fclose(input);
return 0;
}
void error(char *s)
{
printf("%s\n", s);
exit(1);
}
ASKER
The books my wife bought me for a hobby are "The C Programming Language, second edition" and "The C Answer Book". The reason I posted this question was so I could use it as a tool to scroll to a bottom of a file. Any help that can show how this program can run and work would be helpful.
ASKER
I still receive a error message when I compile the program.
ASKER CERTIFIED SOLUTION
membership
This solution is only available to members.
To access this solution, you must be a member of Experts Exchange.
Also, no file is indicated. What is being tailed? I will try to touch up the code so that you can tail a user-specified file.