ハマっている「お菓子」を教えて!

名簿管理システムとしてメンバの追加、メンバの削除、メンバリストを名前順(アルファベット昇順)で表示、メンバリストのファイル出力
引数としてファイルパスを指定することによるメンバ初期データの読込ができるプログラムを以下のように作成しました。

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

typedef struct tagNode{
int no;
char name[30];
struct tagNode *next;
}Node;

Node *ApndNode(Node *top, int no, char *name)
{
if(top == NULL){
top = (Node*)calloc(1, sizeof(Node));
top->no = no;
strcpy(top->name, name);
top->next = NULL;
}else{
if(strcmp(top->name, name) > 0){
Node *p = (Node*)calloc(1, sizeof(Node));
p->no = no;
strcpy(p->name, name);
p->next = top;
top = p;
}else{
top->next = ApndNode(top->next, no, name);
}
}
return top;
}

Node *DltNode(Node *top, int no, char *name)
{
if(top != NULL){
if(top->no == no && !strcmp(top->name, name)){
Node *p = top->next;
free(top);
top = p;
}else{
top->next = DltNode(top->next, no, name);
}
}
return top;
}

void PrintList(Node *top)
{
if(top != NULL){
printf("%-10d %s\n", top->no, top->name);
PrintList(top->next);
}
}

void PrintFile(Node *top)
{
FILE *fp;
char file_name[256];
Node *p = top;
printf("file name : "); scanf("%s", file_name);
fp = fopen(file_name, "w");
if(!fp) return;
while(p != NULL){ fprintf(fp, "%d %s\n", p->no, p->name); p = p->next;}
fclose(fp);
}

void FreeList(Node *top)
{
while(top != NULL){
Node *p = top->next;
free(top);
top = p;
}
}

int main(int argc, char *argv[])
{
Node *top = NULL;
int no, op;
char name[30];

while ((op = getopt(argc, argv, "f:")) != -1){
switch (op){
case 'f':
do{
FILE *fp = fopen(optarg, "r");
if(!fp) break;
while(fscanf(fp, "%d%s", &no, name) == 2) top = ApndNode(top, no, name);
fclose(fp);
}while(0);
}
}

while(1){
printf("--------command--------\n");
printf("1.Append\n2.Delete\n3.Show\n4.Save\n5.Quit\n");
printf("-----------------------\n");
printf("op : "); scanf("%d", &op);
if(op == 5) break;
switch(op){
case 1: printf("no : "); scanf("%d", &no);
printf("name : "); scanf("%s", name);
top = ApndNode(top, no, name);
break;
case 2:
printf("no : "); scanf("%d", &no);
printf("name : "); scanf("%s", name);
top = DltNode(top, no, name);
break;
case 3: printf("=========list==========\n");
printf("<no> <name>\n");
PrintList(top);
printf("=======================\n");
break;
case 4: PrintFile(top);
break;
}
}
FreeList(top);

return 0;
}

このプログラムに名前によって検索できる機能をつけるにはどのようにすればよいのでしょうか?教えてください。

A 回答 (1件)

★アドバイス


・まずはメニューに検索を追加してみましょう。
 static const char *menu[] = {
  "--------command--------",
  "1.Append",
  "2.Delete",
  "3.Show",
  "4.Save",
  "5.Find", ←これ追加
  "9.Quit",
  "-----------------------",
  NULL,
 }; int i;
 
 // メニューの表示部
 for ( i = 0 ; menu[i] != NULL ; i++ ){
  puts( menu[i] );
 }
・あと switch 文にも追加。
 Node *find; ←宣言部に追加。
 
 switch ( op ){
  case 1:
   :
   省略
   :
  case 5:
   printf( "name : " ); scanf( "%s", name );
   find = FindNode( top, name ); ←name 文字列を検索して見つかったらそのポインタを返す
   DispNode( find ); ←1つのノードを表示する関数
   break;
 }
・検索用の関数は次のようにすれば良い。

// 名前で検索
Node *FindNode( Node *top, const char name[] )
{
 for ( ; top != NULL ; top = top->next ){
  if ( !strcmp(top->name,name) ){
   return top; ←見つかった場合
  }
 }
 return NULL; ←見つからない場合
}

その他:
・無限ループは while (1){ … } 以外にも for ( ; ; ){ … } でも出来ます。
 void DispNode( Node *node ); は自分で作成してみて下さい。
 ↑
 この関数は node=NULL の場合は何も表示しないようにします。
・以上。
    • good
    • 0
この回答へのお礼

ありがとうございます。早速やってみます。

お礼日時:2007/06/27 00:15

お探しのQ&Aが見つからない時は、教えて!gooで質問しましょう!


おすすめ情報