ページ 11

連結リスト構造

Posted: 2011年7月27日(水) 16:11
by yuuma
何度も同じような内容の質問ですみません・・・
辞書引きプログラムをつくる過程で辞書から単語の情報を読み込んで表示するプログラムを作れという学校の課題に取り組んでます。

ちなみに辞書データは
北海道、名詞、固有名詞、地域、一般、ホッカイドウ
ポプラ、名詞、一般、ポプラ
    ・   
    ・
みたいな感じで3000行ぶんくらいあります。
あいうえお順はバラバラですが、そのままリストに格納してます。

コード:

#include <stdio.h>
#include <stdlib.h>
#include <string.h>

#define MAXBUFFERSIZE 10000

typedef struct ZishoListNode{

  char data[128];/* 単語データ */
  struct ZishoListNode *next;/* 次のノードへのポインタ */
} ZishoListNode;

typedef struct ZishoList{

  int node_num;/* 辞書データの総数 */
  struct ZishoListNode *head;/* 先頭ノードへのポインタ */
} ZishoList;


ZishoListNode *ZishoListNodeAlloc(void)/* ノードの領域確保関数 */
{
    ZishoListNode *node;
    node = (ZishoListNode *)malloc(sizeof(ZishoListNode));
    if (node == NULL) { 
	return (NULL);
    }
    node->next = NULL;
    return (node);
}

ZishoList *ZishoListAlloc(void)/* リストの領域確保関数 */
{
    ZishoList *list;

    list = (ZishoList *)malloc(sizeof(ZishoList));
    if (list == NULL) { 
	return (NULL);
    }
    list->node_num = 0;
    list->head = NULL;
    return (list);
} 


ZishoListNode *ZishoListDataAdd(ZishoList *list, char *x)/* リストにデータを追加する関数 */
{
    ZishoListNode *ptr; /* 注目ノード */
    ZishoListNode *prev; /* 直前ノード */
    ZishoListNode *new_node;/* 新しく追加するノード */

    ptr = list->head;
    prev = NULL;

      

    while(ptr != NULL)/* 最後までたどる */
      {
	prev = ptr;
	ptr = ptr->next;
      }
   
    new_node = ZishoListNodeAlloc();/* 新しく追加するノードの領域確保 */
    if (new_node == NULL) {
	exit (0); 
    }

    new_node->data = x;
    new_node->next = NULL;
    prev->next = new_node;/* それぞれ更新 */

    list->node_num++;/* 総数も更新 */

     return (new_node);

}


ZishoList *ZishoListMake(char *filename)
{  
    FILE *fp;
    ZishoList *list;
    char buffer[MAXBUFFERSIZE];

    
    if ((fp = fopen(filename, "r")) == NULL) {
	fprintf(stderr, "No Such File : %s\n", filename);
	exit (1);
    }

    list = ZishoListAlloc();
    if (list == NULL) { 
	exit (0); 
    }

    while (fgets(buffer, MAXBUFFERSIZE, fp)) { 
	buffer[strlen(buffer) - 1] = '\0'; /* 改行文字削除 */
	LinkedListDataAdd(list, buffer);
    }
    fclose(fp);

    return (list);
}


void ZishoListFree(ZishoList *list)/* 領域開放関数 */
{
    ZishoListNode *ptr;
    ZishoListNode *rem; 

    ptr = list->head;

    while (ptr) { 
	rem = ptr;
	ptr = ptr->next;
	free(rem);
    }
    free(list);
}


void ZishoListPrint(ZishoList *list)/* リストの中身を表示する関数 */
{
    ZishoListNode *ptr;
    
    ptr = list->head;
    while (ptr) {
	printf("%s\n", ptr->data);
	ptr = ptr->next;
    }
    
}



int main(int argc, char *argv[])
{
   

  struct ZishoList *list;
  
  list = ZishoListMake(argv[1]);

  printf("Read %d data\n", list->node_num);

  ZishoPrint(list);

  ZishoListFree(list);

  return 0;

}
連結リスト構造でつくってみたんですが、プログラムがうまく作動しません・・・
連結リストの要素がint型なら何度もつくったことあるのですが、char型は初めてなもので・・・
どこが誤っているか教えていただけないでしょうか?
おそらく自作したZishoListMakeとZishoListDataAddが怪しいです。
プログラム長くて読みにくいかもですがよろしくお願いします!

Re: 連結リスト構造

Posted: 2011年7月27日(水) 16:12
by yuuma
補足です
67行目new_node->data = x;っておかしい気がしなくもないのですが・・・

Re: 連結リスト構造

Posted: 2011年7月27日(水) 16:29
by h2so5
どううまく作動しないかもう少し詳しく書いてください。
yuuma さんが書きました:補足です
67行目new_node->data = x;っておかしい気がしなくもないのですが・・・
ポインタの代入ではなく、文字列のコピーが必要ですね。

char data[128];

char buffer[MAXBUFFERSIZE];
のバッファサイズが対応していないのも問題です。

Re: 連結リスト構造

Posted: 2011年7月27日(水) 16:53
by non
1個めのnodeを追加するとき、69行目がまずいね。

Re: 連結リスト構造

Posted: 2011年7月27日(水) 17:23
by yuuma
h2so5 さんが書きました:どううまく作動しないかもう少し詳しく書いてください。


ポインタの代入ではなく、文字列のコピーが必要ですね。

char data[128];

char buffer[MAXBUFFERSIZE];
のバッファサイズが対応していないのも問題です。
strcpy(new_node->data, x)で大丈夫なのでしょうか?

Re: 連結リスト構造

Posted: 2011年7月27日(水) 17:26
by yuuma
non さんが書きました:1個めのnodeを追加するとき、69行目がまずいね。
あ、ほんとですね・・・
if(prev == NULL)の時はheadをnew_nodeにするかんじなんでしょうか?

Re: 連結リスト構造

Posted: 2011年7月27日(水) 17:29
by h2so5
yuuma さんが書きました:strcpy(new_node->data, x)で大丈夫なのでしょうか?
とりあえず上手く動くか試してみたらどうですか?
yuuma さんが書きました: if(prev == NULL)の時はheadをnew_nodeにするかんじなんでしょうか?
その方法でもできますが、
先頭をダミーノードにするのがよく使われる手法だと思います。

Re: 連結リスト構造

Posted: 2011年7月27日(水) 21:02
by box
どうもあまり適切に字下げできていないようで、
コードがノッペリした印象を受けます。そういうコードはあまり見たくないですね。個人的には。
ご本人はそんな風には思いませんか?

Re: 連結リスト構造

Posted: 2011年7月27日(水) 21:24
by non
だめですよ。こんなインデントは。とても読めないので、VisualStadioに張り付けて、自動インデントして読みました。

Re: 連結リスト構造

Posted: 2011年7月28日(木) 16:27
by yuuma
ごめんなさい。まだ初心者な者で・・・
適切な字下げとはどのようなことを言うのでしょうか?

Re: 連結リスト構造

Posted: 2011年7月28日(木) 16:44
by non
{ } の位置など絶対にこうでないといけないと決められているわけではありませんが、せめてループの中は1段字下げしてください。じゃないと、どこからどこまでループしているのか、パット見てわかりません。

Re: 連結リスト構造

Posted: 2011年7月28日(木) 18:47
by h2so5
yuuma さんが書きました:ごめんなさい。まだ初心者な者で・・・
適切な字下げとはどのようなことを言うのでしょうか?
(慣習や決まりごとのような話ではなく)単純にプログラムが読みやすい字下げです。
最初の投稿で、プログラムが読みにくいことを自覚しているような事を書いていますよね。