Thread: Reading files and manipulate queues

  1. #1
    Registered User
    Join Date
    Sep 2012
    Posts
    50

    Reading files and manipulate queues

    So I am trying to write this function, read_deck, which is:


    **void read_deck(char *filename, queue *deck)**


    This function takes a character string of a file name. It opens the file filename for reading. It then reads cards one at a time into the queue deck so that the order tin which they appear in the file is identical to the order they appear in the queue. Cards are read until the end of a file is reached at which point the file is closed and the function returns.


    **int main(int argc, char **argv)**


    Main will set up the queue deck and use read_deck to fill it up with cards from the file designated by the first command line argument. It will then print the deck size and all cards in it (functions length and print_list) will be useful for this.


    My program currently : not done and not sure how to approach it further


    Code:
      #include "libcardlist.h"
        #include <stdio.h>
        
        void read_deck(char *filename, queue *deck);
        
        
        int main(int argc, char **argv){
        
            char *filename = argv[1];
            FILE *f = fopen(filename, "r"); // open file
            char buf[1024]; 
            stack *deck = new_stack(); // new deck
            int status;
            card cards;
            
            //how to set up the queue
            read_deck(    ,     ) // what would be the fields here?
            
            
            
            
        }
        void read_deck(char *filename, queue *deck){
          
          for (status = fscanf(f,"%s", buf); 
                 status != EOF; 
                 status = fscanf(f,"%s", buf))
                 {
                    fscanf (f,"%d%c", &cards.face,&cards.suit);
                    printf (" %d%c\n",cards.face,cards.suit);
                 }
        }
    for my current read_deck, it only prints every other card for some reason..
    This is the desired output:


    gcc p2.c libcardlist.c
    lila [program1]% cat smalldeck.cards
    14S
    2D
    13C
    10H
    5H
    11C
    13S
    4D
    13D
    lila [program1]% a.out smalldeck.cards
    Deck 9: 14S 2D 13C 10H 5H 11C 13S 4D 13D


    mine output right now:



    2D
    10H
    11C
    4D
    4D




    the libcardlist.c (correct)
    Code:
        /* This file contains functions to operate on a lists, stacks, and
           queues of cards */
        
        #include <stdio.h>
        #include <stdlib.h>
        
        /* Report an error and exit the program with a failure */
        void cardlist_error(char *msg){
          fprintf(stderr,"libcardlist: %s\n",msg);
          exit(EXIT_FAILURE);
        }
        
        /* Basic type for a card */
        typedef struct {
          int face;            /* 2-14 */
          char suit;            /* C H S D */
        } card;
        
        /* Convert a string like 14D into a card */
        card str2card(char *buf){
          card c;
          sscanf(buf,"%d%c",&c.face,&c.suit);
          return c;
        }
        
        /* Given a card c, put a string like 14D in buf representing it.  Good
           for printing  */
        char *card2str(card c, char *buf){
          sprintf(buf, "%d%c", c.face, c.suit);
          return buf;
        }
        
        /* Lists are of cards */
        typedef card node_data;
        
        /* List Functions */
        
        /* Basic type for a list: data and next */
        typedef struct node {
          node_data data;
          struct node *next;
        } node;
        
        /* Returns how many nodes are in a list */
        int length(node *l){
          int n = 0;
          while(l != NULL){
            n++;
            l = l->next;
          }
          return n;
        }
        
        /* Reverses a list, creates a fresh and distinct copy of the list */
        node *reverse(node *l){
          node *r = NULL;
          while(l != NULL){
            node *new = malloc(sizeof(node));
            new->data = l->data;
            new->next = r;
            r = new;
            l = l->next;
          }
          return r;
        }
        
        /* Print a list of cards to a file pointer */
        void print_list(node *l, FILE *f){
          char buf[1024];        /* Use this for string conversion */
          while(l != NULL){        /* Til end of list */
            fprintf(f,"%s ", card2str(l->data,buf)); /* Convert to string and print */
            l = l->next;                 /* Advance to next */
          }
          fprintf(f,"\n");
        }
        
        
        /* Stack functions */
        
        /* Basic type for a stack */
        typedef struct stack {
          node *top;
        } stack;
        
        /* Make a new stack: allocate memory and set its top pointer to
           initially be NULL for an empty stack */
        stack *new_stack(){
          stack *s = malloc(sizeof(stack));
          s->top = NULL;
          return s;
        }
        
        /* Return 1 if the stack is empty and 0 otherwise  */
        int stack_empty(stack *s){
          return s->top == NULL;
        }
        
        /* Push something on the top of the stack */
        void stack_push(stack *s, node_data p){
          node *new = malloc(sizeof(node)); /* New node for the new data */
          new->data = p;            /* New node gets the new data */
          new->next = s->top;            /* new will be on top, point it at current top */
          s->top = new;                /* new is on top now */
        }
        
        /* Remove the top element of the stack */
        void stack_pop(stack *s){
          if(!stack_empty(s)){        /* If the stack is not empty */
            node *remove = s->top;    /* Track what's being removed */
            s->top = s->top->next;    /* Advance the top down one */
            free(remove);        /* Get rid of the old top node */
          }
        }
        
        /* Retrive data from the top of the stack */
        node_data stack_top(stack *s){
          if(!stack_empty(s)){        /* If the stack is not empty */
            return (s->top->data);    /* Return the data */
          }
          else{                /* Otherwise there is an error */
            cardlist_error("stack_top called on empty stack");
          }
        }
        
        /* Queue functions */
        
        /* Basic type for the queue data structure */
        typedef struct queue {
          node *front;            /* Front of the line */
          node *rear;            /* Back of the line */
        } queue;
        
        /* Make a new queue which is initially empty */
        queue *new_queue(){
          queue *q = malloc(sizeof(queue));
          q->front = NULL;
          q->rear = NULL;
          return q;
        }
        
        /* Returns 1 if the queue is empty and 0 otherwise */
        int queue_empty(queue *q){
          return q->front == NULL;
        }
        
        /* Add something to the front of the queue */
        void queue_add(queue *q, node_data p){
          node *new = malloc(sizeof(node)); /* Adding a new node */
          new->data = p;            /* Set new node's data */
          new->next = NULL;            /* It will be the end of the line */
          if(queue_empty(q)){        /* First node to be added */
            q->front = new;        /* Front and back are new node */
            q->rear = new;
          }
          else {            /* Not first node */
            q->rear->next = new;    /* Current rear is second to last */
            q->rear = new;        /* new guy is last */
          }
        }
        
        /* Remove first element of the queue */
        void queue_remove(queue *q){
          if(!queue_empty(q)){        /* If the queue is not empty */
            node *remove = q->front;    /* Track who is being removed */
            q->front = q->front->next;    /* Second in line is now at front */
            free(remove);        /* Remove the old front */
          }
        }
        
        /* Get the data for the front of the queue */
        node_data queue_front(queue *q){
          if(!queue_empty(q)){        /* If queue is not empty */
            return (q->front->data);    /* Get data for front node */
          }
          else{                /* Otherwise this is an error */
            cardlist_error("queue_front called on empty queue");
          }
        }

  2. #2
    and the hat of int overfl Salem's Avatar
    Join Date
    Aug 2001
    Location
    The edge of the known universe
    Posts
    39,660
    > This function takes a character string of a file name. It opens the file filename for reading.
    So consider what you're doing in main, which is opening a file.

    > stack *deck = new_stack(); // new deck
    The function seems to want a queue, not a stack.

    > for my current read_deck, it only prints every other card for some reason..
    That's because it's doing fscanf TWICE in each loop.
    Try say
    while ( fscanf(f,"%s", buf) == 1 )
    or
    for ( ; fscanf(f,"%s", buf) == 1 ; )

    Each reads one more string from the file, and for each successful read, runs the body of the loop (where you can sscanf / print / whatever)
    If you dance barefoot on the broken glass of undefined behaviour, you've got to expect the occasional cut.
    If at first you don't succeed, try writing your phone number on the exam paper.

Popular pages Recent additions subscribe to a feed

Similar Threads

  1. Replies: 4
    Last Post: 03-29-2012, 02:55 PM
  2. Replies: 1
    Last Post: 11-13-2010, 11:59 PM
  3. Replies: 3
    Last Post: 11-13-2010, 11:49 PM
  4. manipulate date on files
    By cnchybrid in forum C Programming
    Replies: 7
    Last Post: 04-19-2007, 12:54 AM
  5. how to list files in a directory, to then manipulate each file.
    By andre in forum A Brief History of Cprogramming.com
    Replies: 5
    Last Post: 03-31-2002, 07:38 PM

Tags for this Thread