2016-03-02 66 views
1

我是一名初学者,所以我的理念给了我一个完成的任务,在这个任务中我需要在链表中输入几个字符串,并且在我输入打印之后,他们需要打印按照正确的顺序,从第一个到最后一个。单链表C打印

这里是我的了:

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

    typedef struct Node { 
     char data; 
     struct Node *next; 
    }node; 

char createlist(node *pointer, char data[100]) { 
    while (pointer->next != NULL) { 
     pointer = pointer->next; 
    } 

    pointer->next = (node*) malloc(sizeof(node)); 
    pointer = pointer-> next; 
    pointer->data = *data; 
    pointer->next = NULL; 
} 

int main() { 
    node *first, *temp; 
    first = (node*) malloc(sizeof(node)); 
    temp = first; 
    temp->next = NULL; 

    printf("Enter the lines\n"); 
    while (1) { 
     char data[100]; 
     gets(data); 
     createlist(first, data); 
     if (strcmp(data, "print") == 0) 
      printf("%s\n", first->data); 
     else if (strcmp(data, "quit") == 0) 
      return (0); 

    }; 

} 

当我运行它,我得到: 输入线: asdfasdf 打印 (空)

任何帮助,因为这可以理解为我的第一次使用链接列表。

+0

注意,他们说[你不应该投的malloc'()的结果在'C](http://stackoverflow.com/questions/605845/do -i-铸造了对结果的-的malloc)。 – MikeCAT

+0

你不应该使用'gets()',它具有缓冲区溢出的不可避免的rsik。 – MikeCAT

+0

您应该首次使用调试器。 –

回答

3
  • 你应该正确地格式化代码。
  • first->data通过malloc()进行分配,未初始化,因此使用其值调用未定义的行为
  • 为了不特别处理第一个元素,您应该使用指针指针createlist()修改first
  • 由于createlist()不会返回任何内容,其返回值的类型应为void
  • 我想你想复制的字符串,而不是分配每个字符串的第一个字符。
  • 要打印您输入的所有内容,必须编写代码。
  • 您不应该使用gets(),这有不可避免的缓冲区溢出风险。
  • 你应该free()无论你通过malloc()分配。

提高代码:

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

typedef struct Node 
{ 
    char *data; 
    struct Node *next; 
} node; 

void createlist(node **pointer, char data[100]) 
{ 
    while (*pointer != NULL) 
    { 
     pointer = &(*pointer)->next; 
    } 

    *pointer = malloc(sizeof(node)); 
    if (*pointer == NULL) 
    { 
     perror("malloc 1"); 
     exit(1); 
    } 
    (*pointer)->data = malloc(strlen(data) + 1); 
    if ((*pointer)->data == NULL) 
    { 
     perror("malloc 2"); 
     exit(1); 
    } 
    strcpy((*pointer)->data, data); 
    (*pointer)->next = NULL; 
} 

int main(void) 
{ 
    node *first = NULL; 

    printf("Enter the lines\n"); 
    while (1) 
    { 
     char data[100], *lf; 
     if (fgets(data, sizeof(data), stdin) == NULL) strcpy(data, "quit"); 
     if ((lf = strchr(data, '\n')) != NULL) *lf = '\0'; /* remove newline character */ 
     createlist(&first, data); 
     if (strcmp(data, "print") == 0) 
     { 
      node *elem = first; 
      while (elem != NULL) 
      { 
       printf("%s\n", elem -> data); 
       elem = elem->next; 
      } 
     } 
     else if (strcmp(data, "quit") == 0) 
     { 
      while (first != NULL) 
      { 
       node *next = first->next; 
       free(first->data); 
       free(first); 
       first = next; 
      } 
      return(0); 
     } 

    } 

} 
+0

谢谢你试图帮忙。我得到这些错误:main.cpp:18:35:错误:无效转换从'void *'到'节点* {aka节点*}'[-fpermissive] *指针= malloc(sizeof(节点)); main.cpp:24:47:错误:从'void *'无效转换为'char *'[-fpermissive] (* pointer) - > data = malloc(strlen(data)+ 1); – Mirakurun

+0

@Mirakurun使用C编译器,而不是C++编译器。这个问题在标题和标记中都标记为C,代码为C.为什么地球上你没有将这些代码编译为C++? – MikeCAT

+0

是的,这是我的坏,甚至没有看到我的扩展是cpp。我只是在Kdevelop上配置了C,它的工作完美无瑕。再次感谢你。 – Mirakurun

0

Inside createlist(),您正在迭代到列表的末尾。在那里,您正在添加一个新节点并设置一个新的输入文本。通过这样做,你错过了你已经有了第一个节点。因为每次调用createlist()都会迭代到最后,所以您每次都跳过第一个节点,因此它仍然没有文本,并且提供了NULL

为了不跳过第一个初始节点,你可以改变createlist()这样的:

char createlist(node *pointer, char data[100]) 
{ 
    while (pointer->data != NULL && pointer->next != NULL) 
    { 
    pointer = pointer->next; 
    } 
    ... 
    ... 
} 

或者你可以不最初创建的第一个节点,但只输入文本的第一行之后。


编辑:这里有两个额外的样式提示:

  • 如果有人进入120个字符会发生什么?文本将超过你的char[100]数组,并将填充其他使用的RAM。这是一个缓冲区溢出。你可以尝试只抓取前100个字符,得到substring。或者,使用长度参数fgets()

  • 创建一个常数为100,如#define MAX_BUFFER_LENGTH 100,并且每次都使用它。

+0

谢谢!你们俩都帮了我很多。 – Mirakurun

+0

很高兴帮助:-)玩得开心。 –