链接列表以从用户获取输入并打印它

时间:2013-12-21 17:53:26

标签: c linked-list malloc

我正在尝试用c编写一个程序来获取用户的输入(字符)。用户应该能够输入他想要的输入(''无限'')。

这是我最终编写的程序,完全没有错误:

代码:

/*
main:

we will try to get an input from the user.
if we succeed, call insert function. 
if we don't succeed, call freeList function.
if we encounter '\n' or EOF, we quit the program.
print the list, the free it.

insert (type void. does not return a value):

if allocation is successful, then we can put a new item in the linked list. 
the item is a type node.
we don't care the number of nodes in the list. 
if allocation is not successful, call free function.

free:
free the memory.

*/

#include <stdio.h>
#include <stdlib.h>
typedef struct list *ptr;
typedef struct list{
    char data;
    ptr next;
}node;  /*describes a linked list.*/
void insert(ptr *H, char c);
void freeList(ptr *H);
void printList(ptr *H);

int main(){
char c;  
printf("enter a string\n");
ptr H=(ptr)malloc(sizeof(node));/*create an empty list. this is its head.*/
while ((c=getchar())!=EOF && c!='\n'){  
    insert(&H,c);
    }
printList(&H); /*print the list*/
freeList(&H); /*free the list*/
printf("\n");
return 0;
}
void insert(ptr *H, char c){
    ptr p1;
    p1=*H;
    ptr T=(ptr)malloc(sizeof(node)); /*try to allocate a new memory cell*/
    if (!T)
    {
        printList(H);       
        freeList(H); /*we should not free H because we will 
            lose the list we've created.*/
    }
    else
    {
        T->data=c;
        while(p1->next)
        {
            p1=p1->next;
        }
        p1->next=T; /*add T to the end of the linked list*/

    }


}
void freeList(ptr *H){
    ptr p1; /*helper pointer*/
    while(*H){      /*while H points to a certain node*/
    p1=*H;
    (*H)=p1->next;
    free(p1);
    }   
}
void printList(ptr *H){ /*a copy of H is sent so no problem working with it.*/
    ptr p1=*H; printf("string is: \n");
    while (p1) /*while H is not null        */
    {
        printf("%c", p1->data);
        p1=p1->next;
    }

}

此代码确实有效,但任何反馈都很好。

3 个答案:

答案 0 :(得分:1)

尝试获取NULL指针的地址可能会导致分段错误 - 您应该使列表的HEAD成为已分配的节点,而不是NULL指针。

通过gdb等调试器运行代码也很有用,它会告诉您线路导致分段错误(并显示调用堆栈)。

解决警告应该相当简单。

  • flag未使用,因此可以删除。
  • 您应该将*H代替H传递给printList
  • 您应该将H代替&H传递给freeList

或者,您可以更改自己的功能,以取代ptr而不是ptr *,因为我认为没有理由通过node ** s ptr *将成为H )。在这种情况下,应该是将{{1}}传递给函数而不用担心它们的指针类型的简单情况(尽管如WhozCraig所说,这可能不是一个好主意)。

答案 1 :(得分:1)

这可能是您正在寻找的内容,并在代码中提供注释来解释发生了什么。使用指针,更重要的是,指针到指针逻辑......不常见......第一次暴露于它。希望这会有所帮助。

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

typedef struct list *ptr;
typedef struct list
{
    char data;
    ptr next;
} node;

void insert(ptr *H, char c);
void freeList(ptr *H);
void printList(ptr H);

int main()
{
    ptr H = NULL;
    int c;

    printf("enter a string\n");

    while (((c=getchar())!=EOF) && c!='\n')
        insert(&H,(char)c);

    printList(H); /*print the list*/
    freeList(&H); /*free the list*/
    printf("\n");
    return 0;
}

void insert(ptr *H, char c)
{
    // NOTE: while the pointer held in the pointer-to-pointer H
    //  is not NULL, move to the next pointer. Notice how we store
    //  the *address* of the 'next' member in our H variable as we
    //  walk. When we reach the end-of-list the value of the address
    //  held in the pointer whos address we're storing in H will be
    //  null. As a bonus, H will hold the address of the pointer we
    //  need to update, which we do.
    while (*H)
        H = &(*H)->next;

    // allocate new node, assigning to the pointer
    //  dereferenced by the address held in *H
    *H = malloc(sizeof(**H));
    (*H)->data = c;
    (*H)->next = NULL;
}

void freeList(ptr *H)
{
    // NOTE: same logic as before. using H as a pointer-to-pointer
    //  to walk through the chain of pointers. each time we save the
    //  value to a temp, advance to the next pointer, and delete the
    //  saved value.
    while (*H)
    {
        ptr tmp = *H;
        *H = (*H)->next;
        free(tmp);
    }
}

void printList(ptr H)
{
    // NOTE: No need for a pointer-to-pointer here.
    while (H)
    {
        printf("%c", H->data);
        H=H->next;
    }
}

所有这些都说,我强烈建议完全消除ptr意识形态,并简单地使用带有星号的正确声明的指针。 C程序员希望看到那些。他们喊道,说“看!我是指针”= O

答案 2 :(得分:1)

递归的freeList函数可以是

void freeList(ptr *H)
{  
   if(*H!=NULL)
   {
    freeList(&(*H)->next);
    free(*H);
   }
}

同样可以重写printList和insert

相关问题