Single Linked List #2
2002-03-04 03:29:56
Category: c:structures
Description: Reads in a file and pushes each line onto a linked list.
Author: detour
Viewed: 10355
Rating: (47 votes)


/* linklst2.c written by detour@metalshell.com
 *
 * Reads in a text file and loads each line onto a
 * single linked list.
 *
 * http://www.metalshell.com/
 *
 */
 
#include <stdlib.h>
#include <stdio.h>
#include <string.h>
#include <unistd.h>
 
struct LL {
  char *line;
  struct LL *next;
};
 
void stripnl(char *);
void push(char *);
void pop();
void pop_all();
void display();
 
/* Global pointer that will always be the beginning
   of the list */
struct LL *MyLinkList;
 
int main() {
  FILE *inFile;
  char fname[40];
  char line[128];
 
  printf("Enter filename to read: ");
  fgets(fname, sizeof(fname), stdin);
  stripnl(fname);
 
  if((inFile = fopen(fname, "r")) == NULL)
    _exit(1);
 
  while(fgets(line, sizeof(line), inFile) != NULL)
    push(line);
 
  fclose(inFile);
 
  /* Cycle through the list and print each line */
  display();
  /* Free the memory */
  pop_all();
 
  return 0;
}
 
void push(char *line) {
  struct LL *current, *new;
 
  /* There will always be one extra allocated memory space that
     MyLinkList->next will point too.  It is very important to
     fill it with 0's so that new->next will be null, that will tell
     us the end of the list */
  new = (struct LL *)malloc(sizeof(struct LL));
  memset(new, 0, sizeof(struct LL));
 
  /* MyLinkList will be null if this is the first time push() has
     been called */
  if(MyLinkList == (struct LL *)NULL) {
    MyLinkList = (struct LL *)malloc(sizeof(struct LL));
    current = MyLinkList;
  } else {
    current = MyLinkList;
    while(current->next != NULL)
      current = current->next;
  }
 
  current->line = (char *)malloc(strlen(line)+1);
  strcpy(current->line, line);
  current->next = new;
}
 
void display() {
  struct LL *current;
 
  if(MyLinkList == NULL)
    return;
 
  current = MyLinkList;
 
  while(current->next != NULL) {
    fprintf(stdout, "Line: %s", current->line);
    current = current->next;
  }
}
 
/* Deletes the last entry on the stack */
void pop() {
  struct LL *current, *prev;
 
  if(MyLinkList == NULL)
    return;
 
  prev = current = MyLinkList;
 
  while(current->next != NULL) {
    prev = current;
    current = current->next;
  }
 
  /* Free the memory we allocated with malloc */
  free(current->line);
  free(current);
 
  memset(prev, 0, sizeof(struct LL));
}
 
void pop_all() {
 
  if(MyLinkList == NULL)
    return;
 
  while(MyLinkList->next != NULL)
    pop();
 
}
 
void stripnl(char *str) {
  while(strlen(str) && ( (str[strlen(str) - 1] == 13) ||
       ( str[strlen(str) - 1] == 10 ))) {
    str[strlen(str) - 1] = 0;
  }
}