掲示板ランキング  フォーマル靴  サンダル  ブーツ  長靴・レインシューズ  上履き  靴下


掲示板利用宣言

 次のフォームをすべてチェックしてからご利用ください。

 私は

 題名と投稿者名は具体的に書きます。
 課題の丸投げはしません。
 ソースの添付は「HTML変換ツール」で字下げします。
 返信の引用は最小限にします。
 環境(OSとコンパイラ)や症状は具体的に詳しく書きます。
 返信の付いた投稿は削除しません。
 マルチポスト(多重投稿)はしません。

掲示板1

管理者用メニュー    ツリーに戻る    携帯用URL    ホームページ    記事検索    ログ    タグ一覧

No.6871

リスト構造
投稿者---るる(2006/12/07 00:48:06)


リスト構造のプログラムを作成しているのですが、うまく動作してくれません。エラーは無いのですが、メモリ参照がうまくいっていないようなのです。


最大255バイトの文字列を保存するリスト構造を作成。
保存は文字コードの昇順にされる。
構造体内容はELEMENT型。

リスト構造体に対する操作は
1、要素の追加
2、要素の探索
3、要素の削除
4、要素の一括解放
5、要素の全表示
の5種類
作成の際はグローバル変数を使ってはいけない。



プログラム
//リスト構造プログラム
//要素の追加、検索、削除を行う

//ヘッダファイル
#include<stdio.h>
#include<stdlib.h>
#include<string.h>

//構造体の宣言
typedef struct element{
    struct element *next;
    struct element *prev;
    char str[256];
}ELEMENT;

//プロトタイプ宣言
void Insert(ELEMENT **root, char *buff);        //追加
ELEMENT* Serch(ELEMENT **root, char *buff);  //探索
void Delete(ELEMENT **root, char *buff);        //削除
void Purge(ELEMENT **root);  //全削除
void Display(ELEMENT **root, char *buff);      //表示
void All_display(ELEMENT **root);   //全表示

int main(void)
{
    ELEMENT *root;
    char *buff;
    
    int choice;
    
    printf("要素の追加、表示、削除、全表示、全削除の何れかを行います。選択肢を選んでください。\n");
    printf("1:追 加\n2:検 索\n3:削 除\n4:全表示\n5:全削除\n6:終 了\n1〜6から選んでください\n-----");
    scanf("%d", &choice);
    
        switch(choice)
        {
            case 1:{
                printf("追加する単語を入力してください\n");
                gets(buff);
                Insert(&root, buff);//追加
                break;
            }
            case 2:{
                printf("検索する単語を入力してください");
                gets(buff);
                Display(&root, buff);//検索、表示
                break;
            }
            case 3:{
                printf("削除する単語を入力してください");
                gets(buff);
                Delete(&root, buff);//削除
                break;
            }
            case 4:{
                All_display(&root);//全表示
                break;
            }
            case 5:{
                Purge(&root);
                break;
            }
            case 6:{
                printf("終了します");
                break;
            }
        }
    
    
    return 0;
}

//要素の追加
void Insert(ELEMENT **root, char *buff)
{
    ELEMENT *temp;
    ELEMENT *pos;
    
    //メモリブロックを確保
    temp = (ELEMENT *)malloc(sizeof(ELEMENT));
    

    
    strcpy(temp->str, buff);//strにbuffをコピー
    //pos = *root;
    
    if(*root == NULL)//何も要素がなかったら
    {
        *root = temp;
    }
    else if(strcmp(buff, pos->str) < 0)//先頭だったら
    {
        temp->next = *root;
        *root = temp;
    }
    else
    {
        while(pos->next != NULL)
        {
            if(strcmp(buff,pos->str) < 0)
            {
                temp->next = pos->next;
                pos->next = temp;
                return;
            }
            else pos = pos->next;
        }
        temp->next = pos->next;
        pos->next = temp;
    }
    return;
}

//削除
void Delete(ELEMENT **root, char *buff)
{
    ELEMENT *p;
    ELEMENT *pos;
    ELEMENT *temp;
    
    
    
    strcpy(temp->str, buff);
    
    pos = *root;
    if(pos != NULL)
    {
        if(strcmp(pos->str, buff) < 0)
        {
            *root = pos->next;
            free(pos);
        }
        while(pos != NULL)
        {
            pos = pos->next;
            
            if(strcmp(pos->str, buff) == 0)
            {
                pos->prev = pos->next;
                free(pos);
            }
            else if(strcmp(pos->str, buff) > 0)
            {
                free(pos);
                pos->prev = NULL;
            }
        }
    }
    else
    {
        printf("リストに単語が存在しません");
        return;
    }
    //pos->prev = pos->next;
}

//全削除
void Purge(ELEMENT **root)
{
    int i;
    ELEMENT *p;
    ELEMENT *pos;
    
    printf("本当に全削除しますか?\n1.Yes\n2.No");
    scanf("%d", i);
    
    if(i == 1)
    {
        pos = *root;
        while(pos != NULL){
            p = pos->next;
            free(pos);
            pos = p;
        }
        printf("全削除しました");
        *root = NULL;
    }
    
}

//探索
ELEMENT* Serch(ELEMENT **root, char *buff)
{
     ELEMENT *pos;
     ELEMENT *temp;
    
    pos = *root;
    if(pos != NULL)
    {
        while(pos != NULL)
        {
            if(strcmp(pos->str, buff))
            {
                pos = pos->next;
            }
        }
        return pos;
    }
    else
    {
        return NULL;
    }
}

//表示
void Display(ELEMENT **root, char *buff)
{
    ELEMENT *pos;
    ELEMENT *temp;
    
    strcpy(temp->str, buff);
    
    Serch(root,buff);
    
    if(pos == NULL)
    {
        printf("入力された単語はありませんでした");
    }
    
    else if(pos != NULL)
    {
        printf("%c\n", pos);
    }
}

//全表示
void All_display( ELEMENT **root)
{   
    ELEMENT *pos;
    
    pos = *root;
    while( pos != NULL )
    {
        printf("%c\n", pos);
        pos = pos->next;
    }
}



この投稿にコメントする

削除パスワード

発言に関する情報 題名 投稿番号 投稿者名 投稿日時
<子記事> Re:リスト構造 6872 ぽへぇ 2006/12/07 07:21:55


No.6872

Re:リスト構造
投稿者---ぽへぇ(2006/12/07 07:21:55)


>メモリ参照がうまくいっていないようなのです。
具体的な関数名を挙げるとか、もう少し現象を絞り込みましょう。
そういうクセをつけると自分でデバッグできるようになります。

>int main(void)
>{
> ELEMENT *root;

例えば、Insertで
> if(*root == NULL)//何も要素がなかったら
としていますが、main で初期化されていないので
うまく動かないでしょうね。

他にも初期化せずに使用している変数が多々あります。
どういうコンパイラを使っているかわかりませんが、
コンパイル時に警告くらい出ていませんか?

あと気づいた範囲では
char *buff;
gets(buff); <- 危険です。




この投稿にコメントする

削除パスワード

No.6873

Re:リスト構造
投稿者---るる(2006/12/07 09:37:26)


レスありがとうございます。

>具体的な関数名を挙げるとか、もう少し現象を絞り込みましょう。

説明不足ですみませんでした。
具体的なものですが、実行し、switch文で選択したらInsert、Purge以外を選ぶと
「問題が発生したので.exeを開けません。この問題をMicrosoftに送信してください」
と出るんです。


>どういうコンパイラを使っているかわかりませんが、コンパイル時に警告くらい出ていませんか?
>
コンパイルした際にエラーも警告も出てませんでした。
コンパイラはBolandC++です。

>char *buff;
>gets(buff); <- 危険です。





この投稿にコメントする

削除パスワード

No.6874

Re:リスト構造
投稿者--- (2006/12/07 09:57:19)


> コンパイルした際にエラーも警告も出てませんでした。

No.6871のソースコードをそのままコピー&ペーストして
Borland C++ Compilerでコンパイルしてみました。
すると、以下の警告が出ました。

警告 W8013 C:\TEMP\temp2\temp2.c 39: 'buff' は、おそらく値が代入される前に使われている(関数 main )
警告 W8013 C:\TEMP\temp2\temp2.c 91: 'pos' は、おそらく値が代入される前に使われている(関数 Insert )
警告 W8013 C:\TEMP\temp2\temp2.c 123: 'temp' は、おそらく値が代入される前に使われている(関数 Delete )
警告 W8080 C:\TEMP\temp2\temp2.c 155: 宣言された 'p' は使われていない(関数 Delete )
警告 W8013 C:\TEMP\temp2\temp2.c 165: 'i' は、おそらく値が代入される前に使われている(関数 Purge )
警告 W8080 C:\TEMP\temp2\temp2.c 203: 宣言された 'temp' は使われていない(関数 Serch )
警告 W8013 C:\TEMP\temp2\temp2.c 211: 'temp' は、おそらく値が代入される前に使われている(関数 Display )
警告 W8013 C:\TEMP\temp2\temp2.c 215: 'pos' は、おそらく値が代入される前に使われている(関数 Display )



この投稿にコメントする

削除パスワード

No.6888

Re:リスト構造
投稿者---るる(2006/12/07 23:13:06)


>No.6871のソースコードをそのままコピー&ペーストして
>Borland C++ Compilerでコンパイルしてみました。
>すると、以下の警告が出ました。

警告の指摘、ありがとうございました。
やはりこちらのコンパイラでも、学校のコンパイラでもコンパイルしても警告は出てきませんでした。(警告のレベルを上げていると聞いたのですが、レベルを上げるにはどうしたら良いんでしょう?)



ご指摘いただいた警告の点を直し、以下のプログラムを完成させました。
おそらく此れで完成だと思いますが…問題点があったらご指摘お願いします


//リスト構造プログラム
//要素の追加、検索、削除を行う

//ヘッダファイル
#include<stdio.h>
#include<stdlib.h>
#include<string.h>

//構造体の宣言
typedef struct element{
    struct element *next;
    struct element *prev;
    char str[256];
}ELEMENT;

//プロトタイプ宣言
void Insert(ELEMENT **root, char *buff);        //追加
ELEMENT* Serch(ELEMENT **root, char *buff);  //探索
void Delete(ELEMENT **root, char *buff);        //削除
void Purge(ELEMENT **root);      //全削除
void Display(ELEMENT **root, char *buff);      //表示
void All_display(ELEMENT **root);            //全表示

int main(void)
{
    ELEMENT *root;
    char buff[256];
    int choice = -1;
    
    root = NULL;
    
    while(choice != 6)
    {
        printf("要素の追加、表示、削除、全表示、全削除の何れかを行います。選択肢を選んでください。\n");
        printf("1:追 加\n2:検 索\n3:削 除\n4:全表示\n5:終 了\n1〜5から選んでください\n-----");
        scanf("%d", &choice);
        getchar();
        switch(choice)
        {
            case 1:{
                printf("追加する単語を入力してください\n----");
                gets(buff);
                Insert(&root, buff);//追加
                break;
            }
            case 2:{
                printf("検索する単語を入力してください\n----");
                gets(buff);
                Display(&root, buff);//検索、表示
                break;
            }
            case 3:{
                printf("削除する単語を入力してください\n----");
                gets(buff);
                Delete(&root, buff);//削除
                break;
            }
            case 4:{
                All_display(&root);//全表示
                break;
            }

            case 5:{
                printf("終了します");
                Purge(&root);
                break;
            }
        }
    }
    
    return 0;
}

//要素の追加
void Insert(ELEMENT **root, char *buff)
{
    ELEMENT *temp;
    ELEMENT *pos;
    ELEMENT *prev;
    
    //メモリブロックを確保
    temp = (ELEMENT *)malloc(sizeof(ELEMENT));
    
    if(temp == NULL)
    {
        printf("メモリ割り当てに失敗しました");
        exit(1);
    }
    memset((void *)temp, 0, sizeof(ELEMENT));   //メモリ初期化
    
    strcpy(temp->str, buff);//strにbuffをコピー
    pos = *root;
    
    if(*root == NULL)//何も要素がなかったら
    {
        *root = temp;
        temp->next = NULL;
    }
    else if(strcmp(buff, pos->str) < 0)//先頭だったら
    {
        *root = temp;
        temp->next = pos;
    }
    else
    {
        prev = pos;
        pos = pos->next;
        
        while(pos != NULL && strcmp(buff,pos->str) >= 0)
        {
                prev->next = temp;
                temp->next = pos;
                return;
        }
        prev->next = temp;
        temp->next = pos;
    }
    return;
}

//削除
void Delete(ELEMENT **root, char *buff)
{
    ELEMENT *p;
    ELEMENT *pos;
    
    pos = *root;
    if(pos != NULL)
    {
        while(pos != NULL)
        {
            if(strcmp(pos->str, buff) < 0)
            {
                *root = pos->next;
                free(pos);
            }
            if(strcmp(pos->str, buff) == 0)
            {
                pos->next->prev = pos->prev;
                pos->prev->next = pos->next;
                free(pos);
            }
            else if(strcmp(pos->str, buff) > 0)
            {
                free(pos);
                pos->prev = NULL;
            }
        pos = pos->next;
        }
    }
    else
    {
        printf("リストに単語が存在しません\n");
        return;
    }
    //pos->prev = pos->next;
}

//全削除
void Purge(ELEMENT **root)
{
    int i;
    ELEMENT *p;
    ELEMENT *pos;
    
    printf("本当に全削除しますか?\n1.Yes\n2.No\n-----");
    scanf("%d", &i);
    
    if(i == 1)
    {
        pos = *root;
        while(pos != NULL){
            p = pos->next;
            free(pos);
            pos = p;
        }
        printf("全削除しました\n");
        *root = NULL;
    }
}

//探索
ELEMENT* Serch(ELEMENT **root, char *buff)
{
    ELEMENT *pos;
    
    pos = *root;
    if(pos != NULL)
    {
    while(pos != NULL)
        {
            if(strcmp(pos->str, buff))
            {
                pos = pos->next;
            }
            
        }
        return pos;
    }
    
    else
    {
        return NULL;
    }
}

//表示
void Display(ELEMENT **root, char *buff)
{
    ELEMENT *pos;
    
    pos = Serch(root,buff);
    
    if(pos != NULL)
    {
        printf("発見されました\n");
        printf("%s\n", pos->str);
    }
    
    else
    {
        printf("入力された単語は存在しませんでした\n");
    }
}

//全表示
void All_display( ELEMENT **root)
{   
    ELEMENT *pos;
    
    pos = *root;
    if(pos != NULL)
    {
        while( pos != NULL )
        {
            printf("%s\n", pos->str);
            pos = pos->next;
        }
    }
    else
    {
        printf("リストに単語が存在しません\n");
    }
}






この投稿にコメントする

削除パスワード

No.6889

Re:リスト構造
投稿者--- (2006/12/07 23:49:58)


コンパイル時のオプションに
-w 警告をすべて表示
-w- 警告を表示しない
というのがあります。
前者を設定しておく方がいいのではないかと思います。



この投稿にコメントする

削除パスワード

No.6894

Re:リスト構造
投稿者--- (2006/12/08 10:33:01)


ソースコードをすべて追いかけたわけではありませんが、
いくつか問題点があります。

1)リストに単語を1個以上登録している状態で、
単語を削除しようとするとプログラムが異常終了する。
異常終了するのは、リストに存在する単語の削除時・
存在しない単語の削除時の両方。

2)リストに単語を1個以上登録している状態で、
リスト中に存在する単語を検索したときに無限ループに陥る。

3)メニューの「5.終了」でリストを全削除した後、
プログラムを終了しない。
ソースコードを見ると、「6」を入力したときに
終了するようになっている。しかし、使う人にはわからない。

4)caseの後に記述する文を{ 〜 }で囲むのは不要。



この投稿にコメントする

削除パスワード

No.6919

Re:リスト構造
投稿者---るる(2006/12/15 21:20:01)


問題点の指摘ありがとうございます。


>リストに単語を1個以上登録している状態で、
>リスト中に存在する単語を検索したときに無限ループに陥る。
>
>メニューの「5.終了」でリストを全削除した後、
>プログラムを終了しない。
>ソースコードを見ると、「6」を入力したときに
>終了するようになっている。しかし、使う人にはわからない。
>
>caseの後に記述する文を{ 〜 }で囲むのは不要。

以上の問題は解決したのですが、まだ数点の問題点があるんです。


1、削除がうまく行かない
   要素を4つ以上登録している時に、先頭から2番目の要素を消そうと   すると不正なメモリアクセスといわれます。
   他にも削除に関しては数点。

2、追加した際、昇順に並べられない


以上二つ(細かく見れば多数ですが…)の問題点が解決できません。
ご助力お願いします。


(プログラムは字数の関係で次レスに記載します)


この投稿にコメントする

削除パスワード

No.6920

Re:リスト構造
投稿者---るる(2006/12/15 21:20:17)


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

typedef struct element{
    struct element *next;
    struct element *prev;
    char str[256];
}ELEMENT;

void Insert(ELEMENT **root, char *buff);        //追加
ELEMENT* Serch(ELEMENT **root, char *buff);  //探索
void Delete(ELEMENT **root, char *buff);        //削除
void Purge(ELEMENT **root);      //全削除
void Display(ELEMENT **root, char *buff);      //表示
void All_display(ELEMENT **root);            //全表示

int main(void)
{
    ELEMENT *root;
    char buff[256];
    int choice = -1;
    
    root = NULL;
    
    while(choice != 5)
    {
        printf("要素の追加、表示、削除、全表示、全削除の何れかを行います。選択肢を選んでください。\n");
        printf("1:追 加\n2:検 索\n3:削 除\n4:全表示\n5:終 了\n1〜5から選んでください\n-----");
        scanf("%d", &choice);
        getchar();
        switch(choice)
        {
            case 1:
                printf("追加する単語を入力してください\n----");
                gets(buff);
                Insert(&root, buff);//追加
                break;
            case 2:
                printf("検索する単語を入力してください\n----");
                gets(buff);
                Display(&root, buff);//検索、表示
                break;
            case 3:
                printf("削除する単語を入力してください\n----");
                gets(buff);
                Delete(&root, buff);//削除
                break;
            case 4:
                All_display(&root);//全表示
                break;
            case 5:
                printf("終了します(終了の際、登録されている単語は全て消去されます)");
                Purge(&root);
                break;
            default:
                printf("1〜5の数字を選んでください\n");
        }
    }
    return 0;
}

//要素の追加
void Insert(ELEMENT **root, char *buff)
{
    ELEMENT *temp;
    ELEMENT *pos;
    ELEMENT *prev;
    
    //メモリブロックを確保
    temp = (ELEMENT *)malloc(sizeof(ELEMENT));
    
    if(temp == NULL)
    {
        printf("メモリ割り当てに失敗しました");
        exit(1);
    }
    memset((void *)temp, 0, sizeof(ELEMENT));   //メモリ初期化
    
    strcpy(temp->str, buff);//strにbuffをコピー
    pos = *root;
    
    if(*root == NULL)//何も要素がなかったら
    {
        *root = temp;
        temp->next = NULL;
    }
    else if(strcmp(buff, pos->str) < 0)
    {
        *root = temp;
        temp->next = pos;
    }
    else
    {
        prev = pos;
        pos = pos->next;
        while(pos != NULL && strcmp(buff,pos->str) >= 0)
        {
            prev->next = temp;
            temp->next = pos;
            return;
        }
        prev->next = temp;
        temp->next = pos;
    }
    return;
}

//要素の削除
void Delete(ELEMENT **root, char *buff)
{
    ELEMENT *pos;
    ELEMENT *prev;
    int count = 0;
    
    pos = *root;
    if(pos == NULL)
    {
        printf("リストに単語が存在しません\n");
        return;
    }
    else
    {   
        prev = *root;
        pos = pos->next;
        while(pos != NULL)
        {
            if(strcmp(pos->str, buff) == 0)
            {
                if(pos == *root) 
                {
                    *root = pos->next;
                    count++;
                    break;
                }
                else if(pos->next == NULL ) 
                {
                    prev->next = NULL;
                    count++;
                }
                else if(pos->next != NULL && pos != *root)
                {
                    prev->next = pos->next;
                    count++;
                }
                free(pos);
            }
            prev = pos;
            pos = pos->next;
        }
        if(count > 0)
        {
            printf("入力された単語をリストから削除しました\n");
        }
        else if(count == 0)
        {
            printf("入力された単語は見つかりませんでした\n");
        }
    }
}

//要素の全削除
void Purge(ELEMENT **root)
{
    int i;
    ELEMENT *p;
    ELEMENT *pos;
    
    if(i == 1)
    {
        pos = *root;
        while(pos != NULL){
            p = pos->next;
            free(pos);
            pos = p;
        }
        *root = NULL;
    }
}

//要素の探索
ELEMENT* Serch(ELEMENT **root, char *buff)
{
    ELEMENT *pos;
    
    pos = *root;
    if(pos != NULL)
    {
        while(pos != NULL)
        {
            if(!strcmp(pos->str, buff))
            {
                break;
            }
            pos = pos->next;
        }
        return pos;
    }
    
    else
    {
        return NULL;
    }
}

//要素の表示
void Display(ELEMENT **root, char *buff)
{
    ELEMENT *pos;
    
    pos = Serch(root,buff);
    
    if(pos != NULL)
    {
        printf("発見されました\n");
        printf("%s\n", pos->str);
    }
    
    else
    {
        printf("入力された単語は存在しませんでした\n");
    }
}

//要素の全表示
void All_display( ELEMENT **root)
{   
    ELEMENT *pos;
    
    pos = *root;
    if(pos != NULL)
    {
        while( pos != NULL )
        {
            printf("%s\n", pos->str);
            pos = pos->next;
        }
    }
    else
    {
        printf("リストに単語が存在しません\n");
    }
}



この投稿にコメントする

削除パスワード

No.6921

Re:リスト構造
投稿者--- (2006/12/15 23:22:54)


コードは後で時間があるときに見てみます。
その前に、1点だけ。

要素を全削除するPurge関数で、以前は「本当に削除しますか?」という
確認を求めていましたが、今のコードにはありません。
そのため、変数iの値が不定となります。この状態で1と比較するのはまずいです。
必要があれば、修正後のコードをアップロードしてください。



この投稿にコメントする

削除パスワード

No.6928

Re:リスト構造
投稿者--- (2006/12/18 15:57:07)


こんな感じでしょうか…。

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

#define MAXLEN (255)

typedef struct element {
    struct element *next;
    char str[MAXLEN+2];
} *ELEMENT, elementelem;

enum {
    tsuika = 1, kensaku, sakujo, hyouji, shuuryou
};

void Insert(ELEMENT root, char *buff);
void Search(ELEMENT root, char *buff);
void Delete(ELEMENT root, char *buff);
void Display(ELEMENT root);
void Exit(ELEMENT root);

int main(void)
{
    ELEMENT root;
    int choice;
    char buff[MAXLEN+2], s[3];
    
    /* リストの先頭のダミー要素 */
    root = (ELEMENT) malloc(sizeof(elementelem));
    if (root == NULL)
        fprintf(stderr, "out of memory\n"), exit(EXIT_FAILURE);
    root->next = NULL;
    
    while (1) {
        printf("要素の追加、検索、削除、表示を行ないます。\n");
        printf("1:追加  2:検索  3:削除  4:表示  5:終了\n");
        fgets(s, sizeof(s), stdin), s[strlen(s)-1] = '\0';
        sscanf(s, "%d" , &choice);
        switch (choice) {
        case tsuika:
            Insert(root, buff);
            break;
        case kensaku:
            Search(root, buff);
            break;
        case sakujo:
            Delete(root, buff);
            break;
        case hyouji:
            Display(root);
            break;
        case shuuryou:
            Exit(root);
            break;
        default:
            printf("1〜5の数字を選んでください。\n");
            break;
        }
        if (choice == shuuryou) break;
    }
    return EXIT_SUCCESS;
}

void Insert(ELEMENT root, char *buff)
{
    ELEMENT p, q;
    
    printf("追加する単語を入力してください。\n");
    fgets(buff, MAXLEN+2, stdin), buff[strlen(buff)-1] = '\0';
    putchar('\n');
    
    q = (ELEMENT) malloc(sizeof(elementelem));
    if (q == NULL)
        fprintf(stderr, "out of memory\n"), exit(EXIT_FAILURE);
    
    q->next = NULL;
    strcpy(q->str, buff);
    for (p = root; p->next; p = p->next)
        ;
    p->next = q;
}

void Search(ELEMENT root, char *buff)
{
    ELEMENT p;
    
    printf("検索する単語を入力してください。\n");
    fgets(buff, MAXLEN+2, stdin), buff[strlen(buff)-1] = '\0';
    
    for (p = root; p->next; p = p->next) {
        if (strcmp(p->next->str, buff) == 0) {
            printf("%sが見つかりました。\n\n", buff);
            return;
        }
    }
    printf("%sは見つかりませんでした。\n\n", buff);
}

void Delete(ELEMENT root, char *buff)
{
    ELEMENT p, q;
    
    printf("削除する単語を入力してください。\n");
    fgets(buff, MAXLEN+2, stdin), buff[strlen(buff)-1] = '\0';
    
    for (p = root; p->next; p = p->next) {
        if (strcmp(p->next->str, buff) == 0) {
            q = p->next;
            p->next = q->next;
            free(q);
            printf("%sを削除しました。\n\n", buff);
            return;
        }
    }
    printf("%sは見つかりませんでした。\n\n", buff);
}

void Display(ELEMENT root)
{
    ELEMENT p;
    
    if ((p = root->next) != NULL) {
        for (; p; p = p->next)
            printf("%s\n", p->str);
        putchar('\n');
    }
    else
        printf("リストに単語が存在しません。\n\n");
}

void Exit(ELEMENT root)
{
    ELEMENT p, q;
    
    for (p = root; p; p = q) {
        q = p->next;
        free(p);
    }
}




この投稿にコメントする

削除パスワード

No.6929

Re:リスト構造
投稿者--- (2006/12/18 16:41:30)


少し変えてみました。

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

#define MAXLEN (255)

typedef struct element {
    struct element *next;
    char str[MAXLEN+2];
} *ELEMENT, elementelem;

typedef void (*Func)(ELEMENT, char *);

void Insert(ELEMENT root, char *buff);
void Search(ELEMENT root, char *buff);
void Delete(ELEMENT root, char *buff);
void Display(ELEMENT root, char *buff);
void Exit(ELEMENT root, char *buff);

int main(void)
{
    Func funcs[] = { Insert, Search, Delete, Display, Exit };
    ELEMENT root;
    int choice;
    char buff[MAXLEN+2], s[3];
    
    /* リストの先頭のダミー要素 */
    root = (ELEMENT) malloc(sizeof(elementelem));
    if (root == NULL)
        fprintf(stderr, "out of memory\n"), exit(EXIT_FAILURE);
    root->next = NULL;
    
    while (1) {
        printf("要素の追加、検索、削除、表示を行ないます。\n");
        printf("1:追加  2:検索  3:削除  4:表示  5:終了\n");
        fgets(s, sizeof(s), stdin), s[strlen(s)-1] = '\0';
        sscanf(s, "%d" , &choice);
        if (1 <= choice && choice <= 5) {
            funcs[choice-1](root, buff);
            if (choice == 5) break;
        }
        else
            printf("1〜5の数字を選んでください。\n");
    }
    return EXIT_SUCCESS;
}

void Insert(ELEMENT root, char *buff)
{
    ELEMENT p, q;
    
    printf("追加する単語を入力してください。\n");
    fgets(buff, MAXLEN+2, stdin), buff[strlen(buff)-1] = '\0';
    putchar('\n');
    
    q = (ELEMENT) malloc(sizeof(elementelem));
    if (q == NULL)
        fprintf(stderr, "out of memory\n"), exit(EXIT_FAILURE);
    
    q->next = NULL;
    strcpy(q->str, buff);
    for (p = root; p->next; p = p->next)
        ;
    p->next = q;
}

void Search(ELEMENT root, char *buff)
{
    ELEMENT p = root;
    
    if (p->next == NULL) {
        printf("リストに単語が存在しません。\n\n");
        return;
    }
    
    printf("検索する単語を入力してください。\n");
    fgets(buff, MAXLEN+2, stdin), buff[strlen(buff)-1] = '\0';
    for (; p->next; p = p->next) {
        if (strcmp(p->next->str, buff) == 0) {
            printf("%sが見つかりました。\n\n", buff);
            return;
        }
    }
    printf("%sは見つかりませんでした。\n\n", buff);
}

void Delete(ELEMENT root, char *buff)
{
    ELEMENT p = root, q;
    
    if (p->next == NULL) {
        printf("リストに単語が存在しません。\n\n");
        return;
    }
    
    printf("削除する単語を入力してください。\n");
    fgets(buff, MAXLEN+2, stdin), buff[strlen(buff)-1] = '\0';
    for (; p->next; p = p->next) {
        if (strcmp(p->next->str, buff) == 0) {
            q = p->next;
            p->next = q->next;
            free(q);
            printf("%sを削除しました。\n\n", buff);
            return;
        }
    }
    printf("%sは見つかりませんでした。\n\n", buff);
}

void Display(ELEMENT root, char *buff)
{
    ELEMENT p;
    
    if ((p = root->next) == NULL) {
        printf("リストに単語が存在しません。\n\n");
        return;
    }
    
    for (; p; p = p->next)
        printf("%s\n", p->str);
    putchar('\n');
}

void Exit(ELEMENT root, char *buff)
{
    ELEMENT p, q;
    
    for (p = root; p; p = q) {
        q = p->next;
        free(p);
    }
}




この投稿にコメントする

削除パスワード

管理者用メニュー    ツリーに戻る    携帯用URL    ホームページ    記事検索    ログ    タグ一覧





掲示板提供:(有)リアル・インテグリティ