2016-05-06 9 views
0

大きなプロジェクトの一部としてリンクリストを作成していて、問題が発生しました。このテストケースは、コンマで区切られた範囲の文字列(この場合、範囲は整数またはダッシュで区切られた2つの整数)を取り、それぞれの範囲を単独でリンクされたリストに追加します。現在のところ、最初の2つの範囲しか印刷されていません。理由はわかりません。ここでは、コードは次のとおりです。リンクリストにすべての値が表示されない

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

int main() { 
    char port_list[] = "22-25,80,443-445,4200-4205"; 

    struct range_list { 
     struct range_list *next; 
     char *range; 
    }; 

    struct range_list *head = (struct range_list*) malloc(sizeof(struct range_list)); 
    head->next = 0; 
    head->range = strtok(port_list, ","); 

    struct range_list *iter = (struct range_list*) malloc(sizeof(struct range_list)); 
    head->next = iter; 
    iter->next = 0; 

    while((iter->range = strtok(NULL, ",")) != NULL) { 
     iter = (struct range_list*) malloc(sizeof(struct range_list)); 
     iter->next = iter; 
     iter->next = 0; 
    } 

    for(iter=head; iter != 0; iter=iter->next) { 
     printf("%s\n", iter->range); 
    } 
} 

現在、出力は次のようになります。

22-25 
80 

、理想的には私が希望:事前に任意の助け

22-25 
80 
443-445 
4200-4205 

感謝を!私はそれが簡単な問題だと確信しています。私はちょうどリンクされたリストを書いて怖がってしまいます。ここで

+0

おっとああの#include '' EOF

+0

がありません。理想は何らかの理由で不平を言っていませんでした。 – DTSCode

+0

更新されました – DTSCode

答えて

0

あなたはITERを上書きされています。一つだけの範囲が文字列であるかどうあなたのコードに問題があり

struct range_list* tmp; 
struct range_list* last; 



while((iter->range = strtok(NULL, ",")) != NULL) { 
    last = iter; 
    tmp = (struct range_list*) malloc(sizeof(struct range_list)); 
    iter->next = tmp; 
    iter = iter->next; 
    iter->next = 0; 
} 
free(last->next); 
last->next = 0; 


for(iter=head; iter != 0; iter=iter->next) { 
    printf("%s\n", iter->range); 
} 
+1

あなたの変更で私はランタイムエラーが発生します。 – DTSCode

+0

@DTSコードはどこにありますか?印刷ループ内にあるかもしれません。ヌル値を印刷しているためです。 – granmirupa

+0

ideone.com/heJvGM – DTSCode

2

while((iter->range = strtok(NULL, ",")) != NULL) { 
     iter = (struct range_list*) malloc(sizeof(struct range_list)); // you are overwriting iter; 
     iter->next = iter; 
     iter->next = 0; 
    } 

はこれを試してみてください。

そこで私はあなたにクリーンな代替案を提案します:

... 
// as before, assuming ther's at least one range 
struct range_list *head = (struct range_list*) malloc(sizeof(struct range_list)); 
head->next = 0; 
head->range = strtok(port_list, ","); 

struct range_list *iter=head, *tmp; 
char *s; 

while((s = strtok(NULL, ",")) != NULL) { 
    // there is a new item. So first create and initialise it 
    tmp = (struct range_list*) malloc(sizeof(struct range_list)); 
    tmp->next=0; 
    tmp->range=s; 
    // then link it to the previous and interate 
    iter->next = tmp; 
    iter = iter->next; 
} 
... 

この1つはheadに入れるべき文字列に少なくとも1つの範囲があることを前提としています。

Online demo

rangeポインタが元のバッファを指していることに注意してください。元のバッファーは変更されていないので、ここで問題はありません。あなたのリンクリストがバッファやその内容よりも長く生存するリスクがある場合は、範囲文字列の安全なコピーを作るためにposixシステムにいる場合はstrdup()と考えることができます。

0

これは動作するようです。私は基本的に誰もが違う言葉で言っていると思います。

Ideone.com

char port_list[] = "22-25,80,443-445,4200-4205"; 
char *range; 
// Create the head and start the tokener. 
struct range_list *iter, *head = calloc(1, sizeof(struct range_list)); 
head->range = strtok(port_list, ","); 

// As long as there is a token append a new item.  
while((range = strtok(NULL, ",")) != NULL) { 
    iter = (struct range_list*) malloc(sizeof(struct range_list)); 
    iter->next = head; 
    iter->range = range; 
    head = iter; 
} 

for(iter=head; iter != 0; iter=iter->next) { 
    printf("%s\n", iter->range); 
} 

OUTPUT

4200-4205 
443-445 
80 
22-25 
関連する問題