2016-05-06 2 views
0

Я пишу связанный список как часть более крупного проекта и столкнулся с проблемой. Этот тестовый тест принимает строку разделенных запятыми диапазонов (где диапазон в этом случае является целым числом или двумя целыми числами, разделенными тире) и добавляет каждый диапазон в отдельный список. В настоящее время он печатает только первые два диапазона, и я не понимаю, почему. Вот код:Связанный список не распечатывает все значения

#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:

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; 
    } 

Попробуйте это:

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

@ DTSCode где вы? Возможно, в контуре печати. потому что вы печатаете нулевое значение. – granmirupa

+0

ideone.com/heJvGM – DTSCode

2

Ваш код имеет вопрос, если есть только один диапазон в строке.

Я поэтому предлагаю вам экологичную альтернативу:

... 
// 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; 
} 
... 

Это один предполагает, что есть по крайней мере один диапазон в строке ввести в head.

Online demo

Обратите внимание, что range указатели указывают на первоначальный буфер. Здесь это не проблема, потому что исходный буфер остается неизменным. Вы можете рассмотреть strdup(), если вы находитесь в системе posix, чтобы сделать безопасную копию строки диапазона, если существует риск того, что ваш связанный список будет работать дольше, чем буфер или его содержимое.

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); 
} 

ВЫВОД

4200-4205 
443-445 
80 
22-25