Umesh said:
/* BEGIN abc_remove.c */
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <limits.h>
#define STRING "abc"
#define ARGV_0 "abc_remove"
#define INITIAL_BUFFER_SIZE 0
struct list_node {
struct list_node *next;
void *data;
};
int get_line(char **lineptr, size_t *n, FILE *stream);
struct list_node *string_node(struct list_node **head,
struct list_node *tail,
char *string);
void list_free(struct list_node *node, void (*free_data)(void *));
int list_fputs(struct list_node *node, FILE *stream);
int main(int argc, char *argv[])
{
FILE *fp;
struct list_node *head, *tail;
int rc;
char *buff;
size_t size;
if (argc > 1) {
size = INITIAL_BUFFER_SIZE;
buff = malloc(size);
if (buff == NULL) {
size = 0;
}
while (*++argv != NULL) {
fp = fopen(*argv, "r");
if (fp == NULL) {
printf("\nfopen() problem with \"%s\"\n", *argv);
free(buff);
exit(EXIT_FAILURE);
}
printf("\n%s open for reading.\n", *argv);
tail = head = NULL;
while ((rc = get_line(&buff, &size, fp)) > 0) {
if (strstr(buff, STRING) == NULL) {
tail = string_node(&head, tail, buff);
if (tail == NULL) {
puts("Node allocation failure.");
free(buff);
fclose(fp);
exit(EXIT_FAILURE);
}
}
}
if (rc == 0) {
puts("realloc returned a null pointer value");
free(buff);
fclose(fp);
exit(EXIT_FAILURE);
}
fclose(fp);
printf("%s closed.\n", *argv);
fp = fopen(*argv, "w");
if (fp == NULL) {
printf("\nfopen() problem with \"%s\"\n", *argv);
free(buff);
exit(EXIT_FAILURE);
}
printf("%s open for writing.\n", *argv);
list_fputs(head, fp);
fclose(fp);
printf("%s closed.\n", *argv);
list_free(head, free);
}
free(buff);
} else {
puts("This program removes all lines\n"
"containing the string \"" STRING "\", "
"from text files"
"\n\nUsage:\\" ARGV_0
" <FILE_1.txt> <FILE_2.txt> ...");
}
return 0;
}
int get_line(char **lineptr, size_t *n, FILE *stream)
{
int rc;
void *p;
size_t count;
count = 0;
while ((rc = getc(stream)) != EOF) {
if (count != -1) {
++count;
}
if (count + 2 > *n) {
p = realloc(*lineptr, count + 2);
if (p == NULL) {
if (*n > count) {
if (rc != '\n') {
(*lineptr)[count] = '\0';
(*lineptr)[count - 1] = (char)rc;
} else {
(*lineptr)[count - 1] = '\0';
}
} else {
if (*n != 0) {
**lineptr = '\0';
}
ungetc(rc, stream);
}
count = 0;
break;
}
*lineptr = p;
*n = count + 2;
}
if (rc == '\n') {
(*lineptr)[count - 1] = '\0';
break;
}
(*lineptr)[count - 1] = (char)rc;
}
if (rc != EOF) {
rc = count > INT_MAX ? INT_MAX : count;
} else {
if (*n > count) {
(*lineptr)[count] = '\0';
}
}
return rc;
}
struct list_node *string_node(struct list_node **head,
struct list_node *tail,
char *string)
{
struct list_node *node;
node = malloc(sizeof *node);
if (node != NULL) {
node -> next = NULL;
node -> data = malloc(strlen(string) + 1);
if (node -> data != NULL) {
if (*head == NULL) {
*head = node;
} else {
tail -> next = node;
}
strcpy(node -> data, string);
} else {
free(node);
node = NULL;
}
}
return node;
}
void list_free(struct list_node *node, void (*free_data)(void *))
{
struct list_node *next_node;
while (node != NULL) {
next_node = node -> next;
free_data(node -> data);
free(node);
node = next_node;
}
}
int list_fputs(struct list_node *node, FILE *stream)
{
while (node != NULL) {
if (fputs(node -> data, stream) == EOF) {
return EOF;
}
if (putc('\n', stream) == EOF) {
return EOF;
}
node = node -> next;
}
return '\n';
}
/* END abc_remove.c */