链接列表不打印所有值

时间:2016-05-06 16:44:53

标签: c linked-list

我正在编写链接列表作为大型项目的一部分,并遇到了一个问题。此测试用例采用一串逗号分隔的范围(在这种情况下,范围是整数或由短划线分隔的两个整数),并将每个范围添加到单个链接列表中。目前,它只打印前两个范围,我不明白为什么。这是代码:

#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

提前感谢您的帮助!我确定这是一个简单的问题。我只是害怕写链接列表,所以我非常缺乏实践。

3 个答案:

答案 0 :(得分: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系统上制作你的范围字符串的安全副本。

答案 1 :(得分: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);
}

试试这个:

var Post = mongoose.Schema({
   image: {data: Buffer, contentType: String}
});

var post= new Post({ });
post.image.data=fs.readFileSync(req.file.path);
post.image.contentType='image/png';

答案 2 :(得分: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