2016-05-13 7 views
1
私は次のようなデータ構造を持つ二重リンクリスト上でプログラムを足すい

:次の関数でC - 双方向リンクリスト常にnull

typedef struct telephoneBookNode { 
    int id; 
    char name[NAME_LENGTH]; 
    char telephone[TELEPHONE_LENGTH]; 
    struct telephoneBookNode * previousNode; 
    struct telephoneBookNode * nextNode; 
} TelephoneBookNode; 

typedef struct telephoneBookList { 
    TelephoneBookNode * head; 
    TelephoneBookNode * tail; 
    TelephoneBookNode * current; 
} TelephoneBookList; 

、私はリンクリストにテキストファイルからデータを読み込み、ファイルの内容は、次のようになります。

/*100, Alice, 0411112222 
101, Bob, 0411112222 
102, Ali, 0411112223*/ 

TelephoneBookList * commandLoad(char* fileName) { 
    TelephoneBookList *(*createList)(TelephoneBookNode*, char[]) = createTelephoneBookList; 

    char entry[100], *temp1, *temp2; 
    TelephoneBookList* aList = NULL; 
    TelephoneBookNode* aNode = NULL; 
    FILE* telephoneListFile = NULL; 
    int countEntry = 0; 
    Boolean check; 

    telephoneListFile = fopen(fileName, "r"); 

    if (!telephoneListFile) 
     return NULL; 
    else { 
     while (fgets(entry, 100, telephoneListFile)) { 
      temp2 = strcpy(temp2, entry); 
      temp1 = strtok(entry, "\n"); 
      check = addressBookEntryCheck(temp1); 

      if (!check) 
       return NULL; 
      else 
       //here I pass aNode pointer to the below function 
       aList = (*createList)(aNode, temp2); 
     } 
     fclose(telephoneListFile); 
     printf("printed"); //This line is reached when program complied 
     return aList; 
    } 
} 

これは、リストを作成するための機能であり、問​​題はここにあり:それはリストに新しいノードを追加doesnot、それだけで新しいものと最初のノードを置き換えます。最後に、リンクされたリストには、テキストファイルの最後の1つのレコードしかありません。コードを修正するにはどうしたらいいですか?ありがとうございました!

TelephoneBookList * createTelephoneBookList(TelephoneBookNode* node, char entry[]) { 
    TelephoneBookList* aList = malloc(sizeof *aList); 
    TelephoneBookNode* aNode = (TelephoneBookNode*) malloc(sizeof *aNode); 
    char *tokens; 

    tokens = strtok(entry, ", "); 
    aNode->id = atoi(tokens); 

    tokens = strtok(NULL, ", "); 
    strcpy(aNode->name, tokens); 

    tokens = strtok(NULL, ", "); 
    strcpy(aNode->telephone, tokens); //Just assigning values to a node 

    //program always go to this block, means `node` is always null 
    if (node == NULL) { 
     aNode->nextNode = NULL; 
     aNode->previousNode = NULL; 
     node = aNode; 

     aList->current = node; 
     aList->head = node; 
     aList->tail = node; 
    } 
    else { //This block is not reached 
     while (node->nextNode) 
      node = node->nextNode; 

     node->nextNode = aNode; 
     aNode->previousNode = node; 

     aList->tail = node->nextNode; 
    } 
    return aList; 
} 

これはエントリをチェックする機能です:関数の呼び出し元がaNodeを渡され、それがそのループ内で変更されないためです

Boolean addressBookEntryCheck(char entry[]) { 
    char *tokens; 

    tokens = strtok(entry, ", "); 

    if(!tokens || strlen(tokens) < 1 || strlen(tokens) > 3) 
     return FALSE; 
    else { 
     if (!isNumber(tokens)) 
      return FALSE; 
     else { 
      tokens = strtok(NULL, ", "); 

      if (!tokens) 
       return FALSE; 
      else 
      { 
       tokens = strtok(NULL, ", "); 

       if (!tokens) 
        return FALSE; 
       else if (!isNumber(tokens) || strlen(tokens) != 10) 
        return FALSE; 
       else 
        return TRUE; 
      } 
     } 
    } 
} 
+0

に追加する新しいエントリを割り当てる失敗した場合addEntryで

aList = createList() while (fgets(entry,sizeof(entry),fp)!=NULL) { if (!addEntry(aList,entry)) { fprintf(stderr, "failed additem item %s\n", entry); } } ... 

は、文字列

int id = 0; char name[NAME_LENGTH]; char telephone[TELEPHONE_LENGTH]; p = strtok(entry, ","); // id if (p != NULL) { id = atoi(p); p = strtok(NULL, ","); // name, store to temporary string if (p != NULL) { strcpy(name,p); p = strtok(NULL, ","); // telephone number, store to temporary string if (p != NULL) { strcpy(telephone,p); // here you can allocate the new node } } } // disclaimer omitted checks for length etc which any good program should have. also make sure you have room for \0 

を解析します'node = ...'はあなたの関数の*呼び出し側*にとって無意味です。そのポインタは値によって渡されます(すべての変更は、関数の中で一度自動ローカル変数になります)。 – WhozCraig

+0

'addressBookEntryCheck'はどのように見えますか?常にtrueを返す場合は、記述した動作が得られます。私があなたの場合は、関数を、リストヘッダーを作成する1つの関数、ノードを追加する1つの関数に従うのが簡単になるようにします。 –

+0

私は関数 'addressBookEntryCheck'を追加しました。実際には' false'を返します。 –

答えて

0

あなたは

createTelephoneBookList 

を呼び出すたびに新しいリスト

TelephoneBookList* aList = malloc(sizeof *aList); 

を作成また、初期化されていないポインタに

temp2 = strcpy(temp2, entry); 

をコピー私が作成するために使用すると、1つの関数を作成することをお勧めリストヘッダ、新しい項目を追加する1つの関数上記strtokのいずれかがリターン0がそうでなければ

TelephoneBookNode* aNode = malloc(sizeof(TelephoneBookNode)); 
aNode->id = id; 
strcpy(aNode->name, name); 
strcpy(aNode->telephone, telephone); 

が続いFYIあなたのaList

0
//program always go to this block, means `node` is always null 
    if (node == NULL) { 
    .... 

。したがって、常に同じ値のaNodeNULL)を渡します。

あなたのコードのロジックを詳細には見ていませんが、aList->headを渡したいと思っているか、すでにを渡しています。