读取文件和操作队列

时间:2012-11-08 01:53:18

标签: c io queue

所以我正在尝试编写这个函数read_deck,它是:

void read_deck(char *filename, queue *deck)

此函数采用文件名的字符串。它会打开文件文件名以供阅读。然后,它一次一张地读取卡片到队列卡片组,以便它们在文件中出现的顺序与它们在队列中出现的顺序相同。读取卡片直到文件结束,此时文件关闭,函数返回。

int main(int argc, char **argv) 

Main将设置队列组并使用read_deck用第一个命令行参数指定的文件中的卡填充它。然后它将打印卡座大小,其中的所有卡(函数长度和print_list)将对此有用。

我的计划目前:没有完成,也不确定如何进一步处理

   #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(  f , deck  ); // what would be the fields here?




}
void read_deck(char *filename, queue *deck){
   int status;
   card cards;
  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);
         }
}

对于我当前的read_deck,它仅出于某种原因打印所有其他卡。 这是所需的输出:

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 

我的产量现在:

 2D
 10H
 11C
 4D
 4D

libcardlist.c(正确)

/* 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");
  }
}

错误:

segmentation fault

2 个答案:

答案 0 :(得分:1)

您的read_deck函数想要从输入文件中读取,但您已在main()中打开了该文件,因此将FILE *f传递给read_deck。原型变成了:

void read_deck(FILE *f, queue *deck);

你可以用:

来称呼它
read_deck(f, deck);

答案 1 :(得分:0)

read_deck中的for循环每次迭代调用两次fscanf。一旦进入for语句,一次进入循环体。 (在执行开始时加一次,但每个函数调用只运行一次。)fscanf(f,"%s", buf)调用写入*buf;虽然没有对数据做任何事情,但这些调用确实消耗了部分文件。 fscanf (f,"%d%c", &cards.face,&cards.suit);行正在抓取数据,但只有其他调用没有消耗的行。

所以你必须选择一个。从for循环中删除fscanf调用(并相应地更新状态检查),或使用sscanf*buf读取。我推荐前者。