Hi,
Here I have my code which exactly functions as nl command in unix. How can I replace my buffer using malloc which reads unlimited line length and where as my code reads 100 char per line.
#include <stdlib.h>
#include <stdio.h>
#include <string.h>
#include <errno.h>
#define MAX_LINE_LENGTH 100
//Prototypes:
void nl_stream (FILE *fpntr,char *file_pathname);
char *get_next_line(FILE *fpntr);
int main(int argc, char *argv[])
{
char *file_pathname;
FILE *fpntr;
int i, error = 0;
//Either read from stdin, or loop through file arguments:
if(argc == 1) {
nl_stream(stdin,"stdin"); }
else
for (i=1; i<argc; i++) {
file_pathname = argv[i];
//See if file_pathname is really a file as opposed to "-" (a dash), meaning stdin:
if (strcmp(file_pathname,"-") != 0) {
//Open the file:
if ((fpntr = fopen(file_pathname, "r")) != NULL) {
//do nl for the open file:
nl_stream(fpntr,file_pathname);
//Close file:
fclose(fpntr); }
else {
//File could not be opened, so just print error message in style of nl,
//but continue with remaining arguments as nl does (return failure code):
fprintf(stderr,"%s: %s: %s\n", argv[0], file_pathname, strerror(errno));
error = 1; } }
else
//file_pathname is "-" (a dash), so use stdin:
nl_stream(stdin,"stdin"); }
if (!error)
return EXIT_SUCCESS;
else
return EXIT_FAILURE;
}
//Extra procedure to carry out the functionality of nl on a stream/FILE*
//(i.e., an already opened file).
//Exits with failure status if a (read) error occurs.
//file_pathname parameter is included to be able to print out better error messages.
void nl_stream(FILE *fpntr, char *file_pathname)
{
//Need static var in procedure to be able to maintain line number between calls:
static int next_line_number = 1;
//Just need char* to hold line since array for line is allocated elsewhere:
char *next_line;
//Repeatedly get next line in file until EOF or error occurs:
while ((next_line = get_next_line(fpntr)) != NULL)
//Check is returned line is blank and print it out appropriately
//depending on whether it is or is not:
if (strcmp(next_line,"") == 0)
printf(" \n");
else
printf("%6d\t%s\n",next_line_number++,next_line);
//Check if NULL return was due to an error and print message and exit if it was:
//(Would indicate a serious problem reading from the stream, so should not happen.)
if (ferror(fpntr)) {
fprintf(stderr,"Error reading from file %s: %s\n", file_pathname, strerror(errno));
exit(EXIT_FAILURE); }
}
//Required function, which gets the next line from the stream and places it into
//a line buffer/array as a valid C string, then returns it.
//Buffer array is created locally and is static so it can be returned.
//Returns string (pointer to line buffer), or else NULL if an error occurs while
//trying to read from the string or if there is an immediate EOF (nothing left in file).
char *get_next_line(FILE *fpntr)
{
//Allocate space to store lines, making static so can return from function:
static char line_buff[MAX_LINE_LENGTH+1]; //Note: include space for '\0'
int buff_pos, next_char;
//Loop throughs chars in file until encounter EOL, EOF, or error,
//placing chars into next position in line_buff:
buff_pos = 0;
while ((next_char = fgetc(fpntr)) != '\n' && next_char != EOF)
line_buff[buff_pos++] = next_char;
//Make sure that line_buff always contains a valid C string:
line_buff[buff_pos] = '\0';
//Check whether to return the string or NULL:
//(Will return NULL only if got EOF back from fgetc and if
//nothing was read from file or there was an error reading.)
if (next_char == EOF && (buff_pos == 0 || ferror(fpntr)))
return NULL;
else
return line_buff;
}
// EOF