• ベストアンサー

mallocの動作について

RadixSort(基数ソート)で名簿のソートを行うプログラムを書いています。 Queueの挿入操作をする関数enqueueで処理が滞ってしまいます。 コンパイルは通りますが、どうやら「ココ→」(2箇所に書いておきました)で示した行が原因で止まってしまうらしいです。 対処方法が分からずに行き詰っています。どなたかご存知の方、教えていただけると嬉しいです。 ソースの前に、簡単ながらアルゴリズムを記しておきます。 1.名簿のテキストファイルを読み込む。 2.各人の名前は左詰で書かれている。 3.名前の右側にアルファベット順で'A'よりも先にくる文字'_'を詰める。 4.名前に使われる文字の種類だけキューを用意する。 5.名前の一番右側の文字を参照し、その文字に対応するキューに名前を入れる。 6.各キューに「落とし蓋」に相当する文字列を入れる。 7.最初のキューから順番にキューの後ろから名前を取り出し、名前の右から2番目の文字に対応するキューに名前を入れる。 8.取り出した名前が「落し蓋」であった場合は、次の番号のキューから名前を取り出すようにする。 9.全てのキューから全ての名前を取り出し、キューに入れなおす作業が終わったら、各キューに再び「落し蓋」をする。 10.以下、7~9の作業を、参照する文字の位置を1つずつずらしながら行う。 11.テキストファイルにソート結果を出力。 #include <stdio.h> #include <string.h> #include <stdlib.h> #define N 80 #define FS '_' //名前の右に詰める文字 typedef struct cell{  struct cell *next;  struct cell *prev;  char ch[N]; }cell; typedef struct queue{  struct cell *init;  struct cell *final; }queue; void enqueue(queue *q, char *x); int dequeue(queue *q, char *x); int main(int argc, char *argv[]){  FILE *fp_from, *fp_to;  char temp[N], endline[N];  int i, j;  queue *q[54]; //0:空白用の文字, 1~52:アルファベット, 53:スペース  for(i = 0; i < 54; i++){   q[i] = (queue *)malloc(sizeof(queue));   q[i]->init = NULL;   q[i]->final = NULL;  }  if(!argc){   printf("Please input a name of a listfile.\n");   return(1);  }  if(argc >= 3){   printf("You can input only two filenames.\n");   return(1);  }  if((fp_from = fopen(argv[0], "r")) == NULL){   printf("Reading error.\n");   return(1);  }  while(feof(fp_from) == 0){   fgets(temp, N, fp_from);   for(i = strlen(temp)-1; i < N; i++) temp[i] = FS; //空白用文字を名前の右側に詰める   enqueue(q[0], temp);  }  for(i = 0; i < N; i++) endline[i] = FS; //各キューの「落とし蓋」を用意  for(i = N-1; i > 0; i--){   for(j = 0; j < 54; j++){ ココ→ enqueue(q[j], endline);  //各キューに「落し蓋」を挿入する   }   for(j = 0; j < 54; j++){    while(1){     dequeue(q[j], temp);     if(temp[0] == FS) break;     if(temp[i] == FS){      enqueue(q[0], temp);     }else if((temp[i] >= 'A') && (temp[i] <= 'Z')){      enqueue(q[temp[i]-'A'+1], temp);     }else if((temp[i] >= 'a') && (temp[i] <= 'z')){      enqueue(q[temp[i]-'a'+27], temp);     }else if(temp[i] == ' '){      enqueue(q[53], temp);     }else{      printf("There was an unavailable symbol.\n");      return(1);     }     free(temp);    }   }  }  if(argc == 1) fp_to = fopen(strcat(argv[0], "_2.txt"), "w");  else fp_to = fopen(argv[1], "w");  for(i = 0; i < 54; i++){   while(1){    if(dequeue(q[i], temp) == 1) break;     fputs(temp, fp_to);      fputc('\n', fp_to);   }  }  fclose(fp_from);  fclose(fp_to);  return(0); } //キューqに1つの要素xを前から入れる。 void enqueue(queue *q, char *x){  cell *r; ココ→ r = (cell *)malloc(sizeof(cell));  strcpy(r->ch, x);  if(!q->init) q->final = r;  r->prev = NULL;  r->next = q->init;  if(q->init) q->init->prev = r;  q->init = r;  return; }

質問者が選んだベストアンサー

  • ベストアンサー
  • fonera
  • ベストアンサー率52% (38/72)
回答No.3

恐れ入ります。 No.2でお答えした者です。 pdfファイルの解説を読みました。 ご自分でお気づきになったようなので問題ないと思いますが、念のため解説しておきます。 ・まず、キューに関して 今回のアルゴリズムにおけるキューは、(実装は双方向になっていますが)リストと、その先頭・末尾を示すポインタで実現できます。 A→B→C→NULL ↑   ↑ 末   先 キューに入れる(エンキュー)は、リストに追加して末尾のポインタを変えるだけ D→A→B→C→NULL ↑     ↑ 末     先 キューから取り出す(デキュー)は、先頭のポインタを変えるだけ(リストから取り除くかはアルゴリズムによる) D→A→B→C ↑   ↑ 末   先 ココまででお気づきかと思いますが、これらは実態(メモリを確保してある部分)とは関係有りません。 その為、テンポラリキューを作ってもポインタ2つ分のメモリが増えるだけです。メモリの節約には、ほとんどなりません。(メモリを節約するなら、そもそも基数ソートは使わない) #どうしても「落とし蓋」の概念を使ってみたいのでしたら、ポインタで実装した方が速いと思います。 #D→A→B→C→NULL #↑ ↑   ↑ #末 蓋   先 >今までmalloc関数の行で止まったことが無かったものでして。 本当に >ココ→ r = (cell *)malloc(sizeof(cell)); でエラーを出して止まりますか? >strcpy(r->ch, x); で止まっていませんか? mallocは、(Cの標準ライブラリ関数を使用しているなら)失敗するとNULLを返します。メモリが確保できない(Windowsであればページングファイルを0にしたうえで、積んでいるメモリ以上のメモリを確保しようとすると簡単に再現できます)と、失敗します。 エラーチェックをしておられない様ですので、チェックを行ってみてはいかがでしょうか?

全文を見る
すると、全ての回答が全文表示されます。

その他の回答 (3)

  • osamuy
  • ベストアンサー率42% (1231/2878)
回答No.4

なんとなくだけど、 >   for(i = strlen(temp)-1; i < N; i++) temp[i] = FS; //空白用文字を名前の右側に詰める これで、文字列の終端を潰してしまって、 > strcpy(r->ch, x); でメモリ破壊を起こしているような。 デバッガで追っかければすぐ分かる話なので、外してるかもしれませんが。 #ところで「落し蓋」は、sentinelと呼ぶ方が一般的かと。

参考URL:
http://ja.wikipedia.org/wiki/%E7%95%AA%E5%85%B5
全文を見る
すると、全ての回答が全文表示されます。
  • fonera
  • ベストアンサー率52% (38/72)
回答No.2

恐れ入ります。 とりあえずざっくり読みましたが、なぜendlineを配列にしているのか良くわかりません。(わざわざ文字列として扱わなくても問題ない気がしますが) しかし、そもそもキューが空かどうかは「落とし蓋」のような事をしなくても、先頭がNULLになっているかどうかでチェックすれば良いのではないかと思います。 実装上の問題と言うよりも、設計段階ですっきり行っていないような気がします。 基数ソートの学習ですか?名簿のソートが目的ですか? そのあたりによって、回答も異なると思います。 *** 基数ソートは高速ですが、バイナリソートと同じく、正しく完璧に実装しようとするととても面倒です。実装リスクが高いので(数万の電話番号のような)長さが同じで分類が少なく非常に多くのリストに対して行うのが常道です。 本当にその速度が必要かどうか、もう一度考えてみることをお勧めします。 その上で、どうしても速度が必要なのであれば、下記の実装をまずすることをお勧めします。 ・エンキュー、デキューを確実に実装する ・キューが空かどうかの関数を実装する ・Nを3(3文字の英字)程度で、正しくソートできるか確認する

tanakarakusamoti
質問者

お礼

あ、これだともう1セットキューを用意するのと変わりませんでしたw foneraさんの仰る3項目についてまずは検討してみますが、やはりこのアルゴリズムで一度作ってみたいと思います。 プログラムが「ココ→」で停止する理由はご存知ないでしょうか。 今までmalloc関数の行で止まったことが無かったものでして。

tanakarakusamoti
質問者

補足

早速のお返事ありがとうございます。 たいへん遅ればせながら、asuncionさんとfoneraさんに質問の補足をしておこうと思います。 今回作っているプログラムの目的は基数ソートの学習にあります。 大学で教わった基数ソート(おそらくfoneraさんの仰っているソートの基本となるものだと思いますが)のアルゴリズムと、 授業を終えて自分なりに思いついたアルゴリズムを 計算時間や領域効率などの観点から比較したく、今回のプログラムを作りながら検討しようと思っています。 思いついたアルゴリズムのもうちょっと詳しい説明を以下のURLに置いておきましたので、お時間など差し支えなければご覧下さい。5分ほどでお読みいただけるかと思います。 http://wisteria.orz.ne.jp/download/RadixSort.pdf

全文を見る
すると、全ての回答が全文表示されます。
  • asuncion
  • ベストアンサー率33% (2126/6288)
回答No.1

「落とし蓋」の概念がよくわかりません。 教えてください。

全文を見る
すると、全ての回答が全文表示されます。

関連するQ&A

  • C言語 エンキューの問題について

    #include <stdio.h> #include <stdlib.h> #include <string.h> #include <time.h> #define MAX_QUEUE_LENGTH 11 // キューに用いる配列の⻑さ #define N 50 //乱数の範囲 typedef struct queue { int array[MAX_QUEUE_LENGTH]; int front; int rear; } Queue; Queue *init_queue() { printf("initialize queue\n"); Queue *queue = malloc(sizeof(Queue)); queue->front = 0; queue->rear = 0; return queue; } void print_test(char *line) { printf("-------------\n"); printf("test: %s\n", line); } void print_front_and_rear_index(Queue *queue) { // キューの front と rear を表示する関数 printf("front:%2d, rear:%2d\n", queue->front, queue->rear); } void print_queue(Queue *queue) { // キューの要素を front から rear まで表示する関数 } void enqueue(Queue *queue, int value) { // エンキューする関数 } void enqueue_test_items(Queue *queue, int n) { for (int i = 0; i < n; i++) { int score = rand() % N; enqueue(queue, score); } } void test_enqueue(Queue *queue) { print_test("print empty queue"); print_queue(queue); print_test("enqueue 10 items"); enqueue_test_items(queue, 10); print_test("print queue"); print_queue(queue); print_test("enqueue a item to full queue"); enqueue(queue, -1); } int main(void) { srand((unsigned)time(NULL)); // 乱数の初期化 Queue *queue = init_queue(); // キューの初期化 test_enqueue(queue); } 以下の雛形に従い,リングバッファによるキューに対して,エンキューする関数 enqueue を実装せよ. 関数 print_front_and_rear_index は,キューの front と rear を表示するための関数である. 問題に対する解答には不要であるがデバッグのために用意した. という問題なのですが関数print_queueは出来ましたが関数queueの中身がわかりませんので良ければ解答をお願いします。 自分が書いた関数print_queueは下に置いておきます 実行結果は数字以外は画像の通りになります。 void print_queue(Queue *queue) { if (queue->front == queue->rear) { printf("queue is empty\n"); } else { for (int i = queue->front; i % MAX_QUEUE_LENGTH != queue->rear; i++) { printf("queue[%2d]: %2d\n", i % MAX_QUEUE_LENGTH, } } }

  • C言語 エンキューの問題について

    #include <stdio.h> #include <stdlib.h> #include <string.h> #include <time.h> #define MAX_QUEUE_LENGTH 11 // キューに用いる配列の⻑さ #define N 50 //乱数の範囲 typedef struct queue { int array[MAX_QUEUE_LENGTH]; int front; int rear; } Queue; Queue *init_queue() { printf("initialize queue\n"); Queue *queue = malloc(sizeof(Queue)); queue->front = 0; queue->rear = 0; return queue; } void print_test(char *line) { printf("-------------\n"); printf("test: %s\n", line); } void print_front_and_rear_index(Queue *queue) { // キューの front と rear を表示する関数 printf("front:%2d, rear:%2d\n", queue->front, queue->rear); } void print_queue(Queue *queue) { // キューの要素を front から rear まで表示する関数 } void enqueue(Queue *queue, int value) { // エンキューする関数 } void enqueue_test_items(Queue *queue, int n) { for (int i = 0; i < n; i++) { int score = rand() % N; enqueue(queue, score); } } void test_enqueue(Queue *queue) { print_test("print empty queue"); print_queue(queue); print_test("enqueue 10 items"); enqueue_test_items(queue, 10); print_test("print queue"); print_queue(queue); print_test("enqueue a item to full queue"); enqueue(queue, -1); } int main(void) { srand((unsigned)time(NULL)); // 乱数の初期化 Queue *queue = init_queue(); // キューの初期化 test_enqueue(queue); } 以下の雛形に従い,リングバッファによるキューに対して,エンキューする関数 enqueue を実装せよ. 関数 print_front_and_rear_index は,キューの front と rear を表示するための関数である. 問題に対する解答には不要であるがデバッグのために用意した. という問題なのですが上手くいかずに添付されている写真の実行結果通りになりません。なのでよければ解答をお願いします

  • C言語での構造体

    C言語で、 キュー構造を作りたいのですが、うまくできません。 途中まで作ったのですが、うまく動きませんでした。 EnqueueやDequeueでデータの出し入れをするのですが、そのままではデータを取り出したときにデータが先頭に来ないので、refreshで先頭に持ってくるようにプログラムを組みました。 ----------------------------------------------------- #include<stdio.h> #define MAXQUEUE 10 typedef struct queue{ int head, tail; char entry[MAXQUEUE]; } Queue; //キュー構造にデータを入れる。 void Enqueue(char item,Queue *q){ q->entry[q->tail]=item; q->tail++; } //キュー構造からデータを取り出す。 void Dequeue(char *item,Queue *q){ *item=q->entry[q->head]; q->head++; } //キュー構造内のデータを先頭にずらす。 void refresh(Queue *q){ while(q->head==0){ q->entry[q->head-1]=q->entry[q->head]; q->head--; q->tail--; } } void main(){ Queue qu; Enqueue('w1',&qu); Enqueue('w2',&qu); Enqueue('w3',&qu); Enqueue('w4',&qu); Dequeue(&qu,&qu); Dequeue(&qu,&qu); refresh(&qu); } ---------------------------------------------------------------- mainからEnqueueやDequeueを呼び出すときに、引数として何を渡せばいいのでしょうか?構造体をそのまま渡してみたのですが、「error C2664: 'Dequeue' : 1 番目の引数を 'Queue *' から 'char *' に変換できません。(新しい機能 ; ヘルプを参照) 指示された型は関連がありません。変換には reinterpret_cast、C スタイル キャストまたは関数スタイルのキャストが必要です。」というエラーを吐いてしまいます。 分かりづらい説明で申し訳御座いませんが、ご回答宜しくお願いいたします。

  • スタックとキューの違いを示すプログラム。

    学校でスタックとキューの違いを示せという課題が出たのですが、どうしてもわからなかったので、苦し紛れに質問させていただきました…。 いろいろ情報を集めて分からないながらにも以下のプログラムを書いてみたのですがスタックはできてもキューが実現できません。 あまり内部の処理を書き変えずに以下のスタックのプログラムをキューに書き換えたいのですがどうしたらいいでしょうか? ポインタを利用した連結リスト構造です。 #include <stdio.h> #include <stdlib.h> struct Cell//構造体Cellの定義 { int element; Cell* p_prev; Cell* p_next; }; void Cell_Initialize(Cell* p)//要素を初期化用 { p->element = -1; p->p_next = NULL; p->p_prev = NULL; } void Push(Cell* p, int val) { Cell* p_temp = p; while(1) { if(p != NULL) { if(p_temp->p_next == NULL) { p_temp->p_next = (Cell*)malloc(sizeof(Cell));//新しいセルを作成するときのメモリの確保 Cell_Initialize(p_temp->p_next);//初期化 p_temp->p_next->element = val; p_temp->p_next->p_prev = p_temp; break; } else { p_temp = p_temp->p_next; } } } } int Pop(Cell* p) { Cell* p_temp = p; int temp; while(1) { if(p != NULL) { if(p_temp->p_next == NULL) { break; } else { p_temp = p_temp->p_next; } } } if(p_temp->p_prev != NULL) { temp = p_temp->element; p_temp->p_prev->p_next = NULL; free(p_temp); p_temp = NULL; return temp; } else if(p_temp->element != -1) { temp = p_temp->element; Cell_Initialize(p_temp); return temp; } return -1; } void main() { Cell* p_list = NULL; p_list = (Cell*)malloc(sizeof(Cell)); Cell_Initialize(p_list); for(int i = 1; i < 7; i++) { int temp; printf("%d文字目入力してください:",i); scanf("%d",&temp); Push(p_list, temp); } while(1) { int temp = Pop(p_list); if(temp != -1) { printf("[%d]\n\n",temp); } else { break; } } } 長文になってしまいすみません。 どなたかよろしくお願いします。

  • 辞書検索プログラムの続きです。

    void read_dic() { char eng2[20], jp2[40]; FILE *fp; int i=0; if((fp=fopen("dic.txt", "r"))==NULL) { printf("\n ファイルがありません\n"); exit(1); } else { printf("読み込み中...\n"); while (!feof(fp)) { fscanf(fp, "%s %s", eng2, jp2); strcpy(table[i].eng, eng2); strcpy(table[i].jp, jp2); i++; if(i>=100){ printf("辞書のテーブルがいっぱいです\n"); fclose(fp); exit(1); } } fclose(fp); printf("読み込み終了\n"); n = i; } } int hash(char *tango) { int h=0,p=256; while (*tango!='\0') { h = h*p + *tango; h = h%BUCKET_SIZE; tango++; } return(h); } struct cell *find(char *tango) { int a; struct cell *q; a=hash(tango); if(bucket[a].chain==NULL) return NULL; else{ q=bucket[a].chain; while ((strcmp(q->eng,tango))!=0){ if(q->next==NULL) return NULL; else q=q->next; } return q; } } 以前の投稿は http://oshiete1.goo.ne.jp/kotaeru.php3?qid=109202

  • キゅー

    ファイルから読み込んだデータ文字列をキゅーにエンキゅーしたりできゆーしたりするプログラムを作っています。 もう少しで完成なんですがちょっとエラーでます。 次のソースのうちどこを変えたらいいか教えてください プラグラム #include <stdio.h> #include <stdlib.h> #include <string.h> /*--- キューを実現する構造体 ---*/ typedef struct { int max; /* キューのサイズ */ int num; /* 現在の要素数 */ int front; /* 先頭要素カーソル */ int rear; /* 末尾要素カーソル */ char (*que)[100]; /* キュー(の先頭要素へのポインタ) */ } Queue; /*--- キューの初期化 ---*/ int QueueAlloc(Queue *q, int max) { q->num = q->front = q->rear = 0; if ((q->que = calloc(max*20, sizeof(char))) == NULL) { q->max = 0; /* 配列の確保に失敗 */ return (-1); } q->max = max; return (0); } //--- キューの後始末 --- void QueueFree(Queue *q) { if (q->que != NULL) { free(q->que); // 配列を解放 q->max = q->num = q->front = q->rear = 0; } } /*--- キューにデータをエンキュー ---*/ int QueueEnque(Queue *q, char *buffer)) { if (q->num >= q->max) return (-1); /* キューは満杯 */ else { q->num++; strcpy(q->que[q->rear++] ,&buffer[0]); if (q->rear == q->max) q->rear = 0; return (0); } } /*--- キューからデータをデキュー ---*/ int QueueDeque(Queue *q, char *buffer)) { if (q->num <= 0) /* キューは空 */ return (-1); else { q->num--; strcpy(&buffer[0],que[q->front++); if (q->front == q->max) q->front = 0; return (0); } } /*--- キューの大きさ ---*/ int QueueSize(const Queue *q) { return (q->max); } /*--- キューに蓄えられているデータ数 ---*/ int QueueNo(const Queue *q) { return (q->num); } /*--- キューは空か ---*/ int QueueIsEmpty(const Queue *q) { return (q->num <= 0); } /*--- キューは満杯か ---*/ int QueueIsFull(const Queue *q) { return (q->num >= q->max); } int main(void) { int i=0,j=0,ret; char buffer[20]; FILE *fpin; Queue que; double ab,ac; char aa[10]; fpin=fopen("input2.txt","r"); //テキストファイルを読み取りモードで開く if (QueueAlloc(&que, 100) == -1) { puts("キューの確保に失敗しました。"); return (1); } while (1) { int m, x; printf("現在のデータ数:%d/%d\n", QueueNo(&que), QueueSize(&que)); printf("(1) エンキュー (2) デキュー (0) 終了:"); scanf("%d", &m); if (m == 0) break; switch (m) { case 1: if(fgets(&buffer[0],sizeof(buffer),fpin) ==NULL) { puts("もう読み込むデータがありません"); goto END; } if(j>=NUMBER)//読み込む人数がNUMBERを超えてる時の処理 { puts("人数が100人を超えています"); goto END; } j++; printf("データ:%s",&buffer[0]); if (QueueEnque(&que, buffer) == -1) puts("データのエンキューに失敗しました。"); break; case 2: if (QueueDeque(&que, buffer) == -1) puts("デキューできません。"); else { printf("デキューしたデータは%d。\n", &buffer[0]); break; } } } END: QueueFree(&que); fclose(fpin); return (0); } 多分int QueueEnque(Queue *q, char *buffer))と int QueueDeque(Queue *q, char *buffer))の()の中が適切じゃないかも。宣言構文のエラーと出るので。

  • ハッシュ法が得意な人お願いします。

    辞書検索プログラムが実行できません。どこがおかしいか教えてください。 #include <stdio.h> #include <stdlib.h> #include <string.h> #define BUCKET_SIZE 100 typedef struct pointer { struct cell *chain; }pointer; struct cell{ char eng[20]; char jp[40]; struct cell *next; } table[BUCKET_SIZE]; int n; void read_dic(); void init_table(); int hash(char *tango); void main(); struct cell *find(char *tango); struct pointer bucket[BUCKET_SIZE]; void init_table() { int i; for (i=0;i<BUCKET_SIZE;i++){ strcpy(table[i].eng,"0"); strcpy(table[i].jp,"0"); } } void main() { int m; struct cell *p; char tango[20]; read_dic(); while(1){ printf("\n単語を入力: "); scanf("%s", tango); if (strcmp(tango, "*") == 0){ printf("検索を終了\n"); exit(0); } if((p= find(tango)) == NULL) printf("単語は見つかりませんでした\n"); else printf("訳語: %s \n", table[p].jp); } } まだ続きます。。。

  • コンパイルエラー

    前に質問したものですが、ちょっとソースをいじりました。 ファイルから読み込んだデータ文字列をキゅーにエンキゅーしたりできゆーしたりするプログラムを作っています。 コンパイルできて実行できました。 でもエンキューとデキューが実行されてません。 次のソースのうちどこを変えたらいいか教えてください #include <stdio.h> #include <stdlib.h> #include <string.h> #define NUMBER 100 /*--- キューを実現する構造体 ---*/ typedef struct { int max; /* キューのサイズ */ int num; /* 現在の要素数 */ int front; /* 先頭要素カーソル */ int rear; /* 末尾要素カーソル */ char (*que)[NUMBER]; /* キュー(の先頭要素へのポインタ) */ } Queue; /*--- キューの初期化 ---*/ int QueueAlloc(Queue *q, int max) { q->num = q->front = q->rear = 0; if ((q->que = calloc(max*20, sizeof(char))) == NULL) { q->max = 0; /* 配列の確保に失敗 */ return (-1); } q->max = max; return (0); } //--- キューの後始末 --- void QueueFree(Queue *q) { if (q->que != NULL) { free(q->que); // 配列を解放 q->max = q->num = q->front = q->rear = 0; } } /*--- キューにデータをエンキュー ---*/ int QueueEnque(Queue *q, char *buffer) { if (q->num >= q->max) return (-1); /* キューは満杯 */ else { q->num++; strcpy(q->que[q->rear++] ,&buffer[0]); if (q->rear == q->max) q->rear = 0; return (0); } } /*--- キューからデータをデキュー ---*/ int QueueDeque(Queue *q, char *buffer) { if (q->num <= 0) /* キューは空 */ return (-1); else { q->num--; strcpy(&buffer[0],q->que[q->front++]); if (q->front == q->max) q->front = 0; return (0); } } /*--- キューの大きさ ---*/ int QueueSize(const Queue *q) { return (q->max); } /*--- キューに蓄えられているデータ数 ---*/ int QueueNo(const Queue *q) { return (q->num); } /*--- キューは空か ---*/ int QueueIsEmpty(const Queue *q) { return (q->num <= 0); } /*--- キューは満杯か ---*/ int QueueIsFull(const Queue *q) { return (q->num >= q->max); } int main(void) { int i=0,j=0,ret; char buffer[20]; FILE *fpin; Queue que; double ab,ac; char aa[10]; fpin=fopen("input2.txt","r"); //テキストファイルを読み取りモードで開く if (QueueAlloc(&que, 100) == -1) { puts("キューの確保に失敗しました。"); return (1); } while (1) { int m, x; printf("現在のデータ数:%d/%d\n", QueueNo(&que), QueueSize(&que)); printf("(1) エンキュー (2) デキュー (0) 終了:"); scanf("%d", &m); if (m == 0) break; switch (m) { case 1: if(fgets(&buffer[0],sizeof(buffer),fpin) ==NULL) { puts("もう読み込むデータがありません"); goto END; } printf("データ:%s",&buffer[0]); if (QueueEnque(&que, buffer) == -1) puts("データのエンキューに失敗しました。"); break; case 2: if (QueueDeque(&que, buffer) == -1) puts("デキューできません。"); else { printf("デキューしたデータは%d。\n", &buffer[0]); break; } } } END: QueueFree(&que); fclose(fpin); return (0); }

  • バブルソートを使って文字列を辞書順に並べるプログラムを作成したいのです

    バブルソートを使って文字列を辞書順に並べるプログラムを作成したいのですがうま... it200189さん バブルソートを使って文字列を辞書順に並べるプログラムを作成したいのですがうまくいきません・・・。 バブルソートを使って文字列を辞書順に並べるプログラムを作成したいのですが、コンパイルはできますが実行してもうまく出力されません・・・。 どこがおかしいのか、わからないので詳しい方よろしくお願いします。 またこのやり方とは異なる方法で作成できるという方せひプログラムを掲載してください! 参考にさせていただきます! #include<stdio.h> #include<string.h> struct QUEUE{ struct QUEUE *prev; struct QUEUE *next; char alpha[]; }; static struct QUEUE name[10]; void InQueue(struct QUEUE * dst ,struct QUEUE *src){ src->prev = dst->prev; src->next = dst->prev->next; dst->prev = src; dst->prev->next = src; } void DeQueue(struct QUEUE *src){ src->prev->next = src->next; src->next->prev = src->prev; } void InitQueue(struct QUEUE *pQueue ,int size){ int i; struct QUEUE *pEndQueue; struct QUEUE *pTempQueue; pEndQueue = pQueue + size-1; pQueue->prev = NULL; pQueue->next = pEndQueue; pEndQueue->prev = pQueue; pEndQueue->next = NULL; pTempQueue = pQueue + 1; pEndQueue = pEndQueue - 1; pTempQueue->prev = NULL; pTempQueue->next = pEndQueue; pEndQueue->prev = pTempQueue; pEndQueue->next = NULL; i = 3; while ( i < size - 2) { pTempQueue = pQueue + i; InQueue(pEndQueue,pTempQueue); i++; } } void BubbleSort(struct QUEUE *pSort ,int size){ int i; int j; // struct QUEUE *pTemp; // pTemp = pSort; while(size > 0){ i = 0; // pSort = pTemp; pSort = name[1].next; while(i < size - 1){ j = 0; while(pSort->alpha[j] != '\0'){ if(pSort->alpha[j]>pSort->next->alpha[j]){ DeQueue(pSort->next); InQueue(pSort,pSort->next); break; } else if(pSort->alpha[j]<pSort->next->alpha[j]){ pSort = pSort->next; break; } j++; } i++; } size--; } } void main(){ int i; // static struct QUEUE name[10]; struct QUEUE *pStr; char str[4][10] = {"tani","okada","naka","oka"}; InitQueue(name,8); i = 0; while(i<4){ strcpy(name[i + 2].alpha,str[i]); i++; } BubbleSort(name[1].next,4); pStr = name[1].next; i = 0; while(i<4){ printf("%s\n",pStr->alpha); pStr = pStr->next; i++; } }

  • Cプログラムで15パズルを作ってみたのですがうまく動作しません。何処が

    Cプログラムで15パズルを作ってみたのですがうまく動作しません。何処が間違っているのかずっと考えているのですがいまだに解決策が見つかりません。ヒントでもいいのでお願します。 #include <stdio.h> int init(void); void show(void); int chk_cmp(void); char input(void); int move(char cmd); #define N 4 int panel[N][N] = { { 1, 2, 3, 4}, { 5, 6, 7, 8}, { 9, 10, 11, 0}, {13, 14, 15, 12} }; int x, y; int main(void) { printf("これは15パズルです。\n" "左上から右に向かって「1」から「15」が並ぶよう,\n" "「0」を動かしてください。\n" "操作はテンキーで行います。( 8(上),4(左),6(右),2(下) )\n"); if( !init() ) { printf("パネルの初期化に失敗しました。「0」のパネルがありません。\n"); return 1; } while(1) { show(); if( chk_cmp() ) { printf("完成です!\n"); break; } while(1) { if( move(input()) ) { break; } else { printf("そっちには動かせません。\n"); } } } return 0; } int init(void) { int i,j; for(i=0;i<=N-1;i++){ for(j=0;j<=N-1;j++){ if(panel[i][j]==0){ x=j; y=i; return 1; } } } return 0; } void show(void) { int i,j; printf("---------------\n"); for(i=0;i<=N-1;i++){ for(j=0;j<=N-1;j++){ printf("%3d",panel[i][j]); } printf("\n"); } printf("---------------\n\n"); } int chk_cmp(void) { int i,j; for(i=0;i<=N-1;i++){ for(j=0;j<=N-1;j++){ if(i==N-1&&j==N-1){ if(panel[i][j]!=0){ return 0; } }else{ if(panel[i][j]!=N*i+j+1){ return 0; } } } } return 1; } char input(void) { int comand; while(1){ scanf("%d",&comand); if(comand==8||comand==4||comand==6||comand==2){ break; } printf("8(上),4(左),6(右),2(下)を入力してください。"); } return comand; } int move(char cmd) { int dx=0, dy=0; if(cmd==8){dy=-1;}//上 if(cmd==4){dx=-1;}//左 if(cmd==6){dx=1;}//右 if(cmd==2){dy=1;}//下 if(x+dx>=0&&x+dx<=N-1&&y+dy>=0&&y+dy<=N-1){ panel[y][x]==panel[y+dy][x+dx]; panel[y+dy][x+dx]==0; y+=dy; x+=dx; return 1; } else{return 0;} }