何度もお世話になっています。
最近C言語を勉強し始めました。
少しわからない所があるので、良ければ教えてください。
以下にソースコードを示します。
#include "stdafx.h"
#include "stdlib.h"
struct LIST
{
char *name;
struct LIST* next;
struct LIST* prev;
};
struct LIST head;
void addlist(void);
void deletelist(void);
void showlist(void);
int _tmain(int argc,_TCHAR* argv[/url])
{
char command;
head.next =&head;
head.prev = &head;
do
{
puts( "コマンドを入力して下さい" );
puts( "名前を追加:a" );
puts( "名前を削除:b" );
puts( "内容を表示:c" );
puts( "終了:q" );
scanf( "%s", &command );
switch( command )
{
case 'a':
addlist();
break;
case 'b':
deletelist();
break;
case 'c':
showlist();
break;
case 'q':
break;
default:
puts( "コマンドが正しくありません" );
break;
}
puts( "" );
fflush( stdin );
}while( command != 'q' );
return 0;
}
void addlist(void)
{
struct LIST *p, *newcell;
char *name;
name = (char*)malloc(sizeof(char));
puts( "追加する名前の値を入力して下さい" );
scanf( "%s", name );
p = head.next;
if( p != NULL )
{
while( p != &head )
{
p = p->next;
}
}
newcell = (struct LIST*)malloc( sizeof(struct LIST) );
if( newcell == NULL )
{
puts( "メモリ不足" );
return;
}
newcell->name = name;
newcell->next = p->next;
newcell->prev = p;
p->next->prev = newcell;
p->next = newcell;
}
void deletelist(void)
{
struct LIST *p;
char *name;
name = (char*)malloc(sizeof(char));
puts( "削除する名前の値を入力して下さい" );
scanf( "%s", name );
p = head.next;
if( p != NULL )
{
while(p != &head && name != p->name)
{
p = p->next;
}
}
if( p == &head )
{
puts( "指定された要素はリスト内に存在しません" );
}
else
{
p->prev->next = p->next;
p->next->prev = p->prev;
free(p);
}
}
void showlist(void)
{
struct LIST *p;
for( p=head.next; p!=&head; p=p->next )
{
printf( "%s\n", p->name );
}
}
コンパイルして試してみると、追加の方は上手くいくのですが、
削除を実行すると打った名前が消えません。
分かる方がいましたら教えていただけませんか?
どこを訂正すれば大丈夫なのかも教えていただければ、
ありがたいです。
多分内容も変な処がたくさんあるとは思いますが
よろしくお願いします。
僕はVisual Studioを使用しています。
doubly linked listの件について
Re:doubly linked listの件について
現行ログに同名のタイトルがあるので混乱を招きやすいですよ。
あと、規約にある通り、プレタグでソースコードを囲まないと見づらいです。
質問の原因の前に、
name には1文字分しか確保されず、メモリ破壊を引き起こします。(削除時の処理も同様)
(確保領域以外にデータを書き込んでいる)
削除できないのは、条件で、文字列の一致を確認していないためです。
リストに格納したポインタと、新しく確保した検索文字列のポインタと一致するはずがないので、
必ず不一致になります。
strcmp() 関数等で文字列の一致をチェックしてください。
あと、その他の点での指摘ですが、
それと、削除時に 名前を保持するために確保したメモリを解放してません。
(リストだけ解放してます)
もうひとつ。
この構造は双方向ループするので、 next, prev 共に NULL になりませんので、
(確認の意味では必要かと思いますが)チェックする必要はありません。
あと、規約にある通り、プレタグでソースコードを囲まないと見づらいです。
質問の原因の前に、
name = (char*)malloc(sizeof(char)); puts( "追加する名前の値を入力して下さい" ); scanf( "%s", name );これはダメです。
name には1文字分しか確保されず、メモリ破壊を引き起こします。(削除時の処理も同様)
(確保領域以外にデータを書き込んでいる)
削除できないのは、条件で、文字列の一致を確認していないためです。
name != p->nameこれだと、ポインタを比較します。
リストに格納したポインタと、新しく確保した検索文字列のポインタと一致するはずがないので、
必ず不一致になります。
strcmp() 関数等で文字列の一致をチェックしてください。
あと、その他の点での指摘ですが、
p = head.next; if( p != NULL ) { while( p != &head ) { p = p->next; } }ここは、
p = &head;で済むと思います。
それと、削除時に 名前を保持するために確保したメモリを解放してません。
(リストだけ解放してます)
もうひとつ。
この構造は双方向ループするので、 next, prev 共に NULL になりませんので、
(確認の意味では必要かと思いますが)チェックする必要はありません。
Re:doubly linked listの件について
レスポンスありがとうございます。
言われてみれば、そのとおりだと思います。
自分でプログラムを組むと間違いだらけで・・・。
色々と回答していただきありがとうございました。
言われてみれば、そのとおりだと思います。
自分でプログラムを組むと間違いだらけで・・・。
色々と回答していただきありがとうございました。