所以我正在尝试编写这个函数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
答案 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
读取。我推荐前者。