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

Обратите внимание, что они говорят [вы не должны отбрасывать результат 'таНос()' в C] (http://stackoverflow.com/questions/605845/do -i-монолитно-заместитель на результат из-таНоса). – 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 *' в 'node * {aka Node *}' [-fpermissive] * pointer = malloc (sizeof (node)); main.cpp: 24: 47: ошибка: неверное преобразование из 'void *' в 'char *' [-fpermissive] (* pointer) -> data = malloc (strlen (data) + 1); – Mirakurun

+0

@ Mirakurun Используйте компилятор C, а не компилятор C++. Этот вопрос отмечен как C как в заголовке, так и в теге, а код - C. Почему вы скомпилировали этот код как C++? – MikeCAT

+0

Да, это было плохо, я даже не видел, что мое расширение - cpp. Я только что сконфигурировал C на Kdevelop и работает безупречно. Еще раз спасибо. – Mirakurun

0

Внутри createlist(), вы повторяете до конца списка. Там вы добавляете новый узел и устанавливаете новый введенный текст. Таким образом, вам не хватает того, что у вас уже есть первый узел. Поскольку вы выполняете итерацию до конца при каждом вызове createlist(), вы каждый раз перепрыгиваете через свой первый узел, поэтому он остается без текста и поставляет NULL.

Чтобы не перепрыгнуть первый исходный узел, вы можете изменить createlist() так:

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

Или вы можете создать первый узел не на начальном этапе, но только после того, как в первой строке текста были введены.


редактировать: Вот два дополнительных намеков типа:

  • Что произойдет, если кто-то входит в 120 символов? Текст обгонит ваш массив char[100] и заполнит ОЗУ, которое используется иначе. Это переполнение буфера. Вы можете попробовать захватить только первые 100 символов, получить substring. В качестве альтернативы используйте аргумент длины fgets()

  • Создайте константу для 100, например #define MAX_BUFFER_LENGTH 100 и используйте ее каждый раз.

+0

Спасибо! Вы оба очень помогли мне. – Mirakurun

+0

Рад помочь :-) весело провести время. –