リストを使ったキュー

フォーラム(掲示板)ルール
フォーラム(掲示板)ルールはこちら  ※コードを貼り付ける場合は [code][/code] で囲って下さい。詳しくはこちら
さっかん

リストを使ったキュー

#1

投稿記事 by さっかん » 18年前

こんにちは。課題の質問なのですが、リストを使ったキューの基本操作で、
data.datというファイル(「ABCDE」が入っている)から一文字ずつ読み取って、キューに格納してそのキューの内容を表示します。そしてキーボードから文字を入力する際に
・0を入力した場合、プログラム終了
・1を入力した場合、一文字Dequeueした後、Dequeueした文字とキューの内容を表示
・その他の文字を入力した場合、その文字をEnqueueした後、キューの内容を表示
というプログラムを作ったのですが・・・
#include <stdio.h>

struct queue{
char key;
struct queue *before;
} ;

struct queuehead{
struct queue *top, *rear;
} q;
init_queue(){
q.top = NULL;
q.rear = NULL;
}

int en(char c, struct queuehead *q){
struct queue *temp;
struct queue *w;
temp = (struct queue *)malloc(sizeof(struct queue));
temp->key = c;
temp->before = NULL;
w = q->rear;
if(q->top==NULL){
q->rear = temp;
q->top = temp;

}
else{
w->before = temp;
q->rear = temp;
}
}
int de(char c, struct queuehead *q){
struct queue *temp;
struct queue *w;
free(q->top);
q->top = q->top->before;
}
main()
{
init_queue();
FILE *fp1;
char c,enter;
if ((fp1 =fopen("data.dat","r"))==NULL){
printf("file open error!!\n");
exit(1);
}
while((c = fgetc(fp1))!=EOF){
en(c,&q);
}
print_queue_list( q );
while(c!='0'){
printf("\nInput data:");
scanf("%c%c",&c,&enter);
if(c=='0'){
}
else if(c=='1'){
printf("Dequeue:%c\n",*q.top);
de(c,&q);
print_queue_list( q );
}
else{
en(c,&q);
print_queue_list( q );
}
}
fclose(fp1);
return 0;
}
このプログラムを更に拡張して、その他の文字を入力した場合、その文字がキューの中にあるか探索して、中にあればその文字を消して、なければその文字をEnqueueするプログラムを作ってみたのですがエラーばかりでコンパイルすらできません;修正お願いします。探索する方法としてはキューを2個用意して予備の方に一度一文字ずつ入れていく時に違う文字がないか探索して、もう一度もとのキューに一文字ずつ戻していくという方法にしなければなりません。頭がこんがらがってしまいぐちゃぐちゃなプログラムになってしまったので、わかり難かったらまるごと修正してもらってかまいません。よろしくお願いします。
#include <stdio.h>
int i=0,j=0;
struct queue{
char key;
struct queue *before;
} ;

struct queuehead{
struct queue *top, *rear;
} q,q1;
init_queue(){
q.top = NULL;
q.rear = NULL;
}

int en(char c, struct queuehead *q){
struct queue *temp;
struct queue *w;
temp = (struct queue *)malloc(sizeof(struct queue));
if(i==0){
temp->key = c;
temp->before = NULL;
w = q->rear;
if(q->top==NULL){
q->rear = temp;
q->top = temp;

}
else{
w->before = temp;
q->rear = temp;
}
}
else if(i==1){
temp->key =c ;
temp->before = NULL;
if(q1->top==NULL){
q1->rear = temp;
q1->top = temp;
}
else{
w->before = temp;
q1->rear = temp;
}
}
else if(i==2){
temp->key = *q1->top ;
temp->before = NULL;
if(q->top==NULL){
q->rear = temp;
q->top = temp;
}
else{
w->before = temp;
q1->rear = temp;
}
}
}
int de(char c, struct queuehead *q){
struct queue *temp;
struct queue *w;
free(q->top);
q->top = q->top->before;
}
main()
{
init_queue();
FILE *fp1;
char c,enter;
if ((fp1 =fopen("data.dat","r"))==NULL){
printf("file open error!!\n");
exit(1);
}
while((c = fgetc(fp1))!=EOF){
en(c,&q);
}
print_queue_list( q );
while(c!='0'){
printf("\nInput data:");
scanf("%c%c",&c,&enter);
if(c=='0'){
}
else if(c=='1'){
printf("Dequeue:%c\n",*q.top);
de(c,&q);
print_queue_list( q );
}
else{
while(q.top='\0'){
i=1;
&c=*q.top;
en(c,&q1);
i=0;
de(c,&q);
if(c==*q.top){
free(q.top);
j=1;
q.top = q.top->before;
}
}
while(*(q.rear.before)!='\0'){
i=1;
de(c,&q1);
i=2;
en(c,&q);
}
if(j!=1){
i=0;
en(c,&q);
}
print_queue_list( q );
j=0;
}
}
fclose(fp1);
return 0;
}

box

Re:リストを使ったキュー

#2

投稿記事 by box » 18年前

最初の方のプログラムは正しく動いていますか?

さっかん

Re:リストを使ったキュー

#3

投稿記事 by さっかん » 18年前

すいません[img]../pic/i/63915.gif[/img]投稿できていませんでした。一つ目のプログラムはちゃんと動きますよ!

box

Re:リストを使ったキュー

#4

投稿記事 by box » 18年前

2つ目のコードは1つ目のコードを拡張されているとのことですので、
念のため1つ目のコードの動きを確認しようと思いました。

このとき、1つ目のコードにprint_queue_list関数のコードがないため、
リンクができませんでした。

同関数のコードを見せていただけますか?

さっかん

Re:リストを使ったキュー

#5

投稿記事 by さっかん » 18年前

print_list_queue.oは先生が用意してくれたものでして、emacsで見たらぐちゃぐちゃだったんですがどうしましょう??

box

Re:リストを使ったキュー

#6

投稿記事 by box » 18年前

*.o は *.c をコンパイルしてできるオブジェクトファイルです。
テキストファイルではなくてバイナリファイルですので、
エディタで見ても中身は全然わからないです。

仕方がないので、1つ目と2つ目のコードを動作確認してみるときは、
print_list_queue関数の中身をこちらで適当に見繕ってみます。

なお、回答に際しては、そのものズバリのコードを提示するかもしれませんし、
ヒントだけを提示するかもしれません。
どちらになるかは、そのときの当方の気分がからんできます。

また、課題の提出期日(いつであるかはわかりませんけれど)に
間に合うように回答できるかどうか、お約束はできません。
技術系掲示板でのやり取りはそういうものであることを、
あらかじめおわかりになっていてください。

box

Re:リストを使ったキュー

#7

投稿記事 by box » 18年前

実は、print_queue_list()の件でリンクができなかったときから
気づいてはいたのですが、1個目のコードにprint_queue_list()のダミーコードを
付け加えた後、C++ではなくCとしてBorland C++ Compilerでコンパイルすると、
こんな風にコンパイルエラーや警告が出るのです。


警告 W8065 D:\My Programs\C\temp1\temp1.c 22: プロトタイプ宣言のない関数 'malloc' の呼び出し(関数 en )
警告 W8070 D:\My Programs\C\temp1\temp1.c 34: 関数は値を返すべき(関数 en )
警告 W8065 D:\My Programs\C\temp1\temp1.c 40: プロトタイプ宣言のない関数 'free' の呼び出し(関数 de )
警告 W8070 D:\My Programs\C\temp1\temp1.c 42: 関数は値を返すべき(関数 de )
警告 W8080 D:\My Programs\C\temp1\temp1.c 42: 宣言された 'w' は使われていない(関数 de )
警告 W8057 D:\My Programs\C\temp1\temp1.c 42: パラメータ 'c' は一度も使用されない(関数 de )
警告 W8057 D:\My Programs\C\temp1\temp1.c 46: パラメータ 'q' は一度も使用されない(関数 print_queue_list )
エラー E2140 D:\My Programs\C\temp1\temp1.c 51: ここでは宣言はできない(関数 main )
エラー E2140 D:\My Programs\C\temp1\temp1.c 52: ここでは宣言はできない(関数 main )
警告 W8065 D:\My Programs\C\temp1\temp1.c 56: プロトタイプ宣言のない関数 'exit' の呼び出し(関数 main )
警告 W8071 D:\My Programs\C\temp1\temp1.c 58: 変換によって有効桁が失われる(関数 main )
警告 W8074 D:\My Programs\C\temp1\temp1.c 68: 構造体が値で渡されている(関数 main )
*** コンパイル中に 2 個のエラーが発生しました ***


51行目と52行目のエラーは、main()の変数定義の前にinit_queue()を呼び出しているためです。
警告の中にも、無視できないものがあります。例えば68行目の警告は

			printf("Dequeue:%c\n", *q.top);

のところなのですが、*q.top というのは何を出力しようとしているのか、
今一つつかみきれないでいます。

こういった状態を確認していたことが、11月9日23:08の投稿につながりました。

さっかん

Re:リストを使ったキュー

#8

投稿記事 by さっかん » 18年前

質問しておいて大変失礼かもしれませんが、自分はプログラミングの知識がまだまだ浅いため、質問にうまく答えられないかもしれませんが、よろしくお願いします。一個目のプログラムは学校ではちゃんと動いていたのですが、環境が違うとエラーが起きるのでしょうか?その辺が残念ながらよくわかりません。それが決定的で解決を断念せざるを得なかったらここまで考えてもらって大変失礼かもしれませんが、断念していただいて結構です。なんか失礼な言い方ですよね;すいません;;
ちなみに
printf("Dequeue:%c\n", *q.top);
は1を入力した際にデキューした文字を表すためにデキューする寸前にq.topの内容を出力するためのものなのでして、実際に実行したら何事もなく出力されていたのですが、書き方がまずかったでしょうか?
ちなみに参考になるかわかりませんが、print_queue_listで表示される内容は
--- Contents of Queue ---
E< -- Rear
D
C
B
A< -- Top
-------------------------
このような感じです。(qの中がABCDEの時)
あと、課題の方はこれは自習課題でして、特に期限もありませんので大丈夫です♪

閉鎖

“C言語何でも質問掲示板” へ戻る