2016-03-02 109 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

很高興幫助:-)玩得開心。 –