在void指针中存储和打印字符串

时间:2016-12-07 13:03:19

标签: c pointers linked-list void-pointers

我编写了一个链表程序,它将数据成员存储为void *。 在尝试使用scanf / printf函数存储和打印时,我遇到了分段错误。

节点定义 - >

typedef struct node {
        struct node *next;
        void *data;
        }node;

主要功能 - >

                head=(node *)malloc(sizeof(node));
                if (head==NULL){
                        printf("error in allocation of memory\n");
                        exit(EXIT_FAILURE);
                }
                tail=(node*)create(head);

创建功能 - >

void *create(node *current)
{
        int user_choice;
        while(current){
                printf("\nEnter the data:");
                scanf("%s",current->data);
                printf("stored at %p\n",(void*)current->data);
                printf("%s",(char*)current->data);
                printf("\nType '1' to continue, '0' to exit:\n");
                scanf("%d",&user_choice);

                if(user_choice == 1){
                        current->next=(node*)malloc(sizeof(node));
                        current=current->next;
                }
                else{
                        current->next=NULL;
                }
        }
        return current;
}

任何人都可以告诉scanf&的正确参数是什么prinf应该是..?

  

在结合答案中给出的点后的工作代码......

void *create(node *current)
{
        node *temp;
        int user_choice;
        while(current){
                printf("\nEnter the data:");
                current->data=(char*)malloc(10*sizeof(char));
                scanf("%s",current->data);
                printf("stored at %p\n",(void*)current->data);
                printf("%s",(char*)current->data);
                printf("\nType '1' to continue, '0' to exit:\n");
                scanf("%d",&user_choice);

                if(user_choice == 1){
                        current->next=(node*)malloc(sizeof(node));
                }
                else{
                        current->next=NULL;
                        temp=current;
                }
                current=current->next;
        }
        return temp;
}

5 个答案:

答案 0 :(得分:3)

在您的代码中,

 scanf("%s",current->data);

尝试使用单位化指针,它会调用undefined behavior

您需要遵循以下两种方法,

  • 使指针指向有效的内存块(例如,使用malloc()和family进行动态分配)
  • 使用数组。

答案 1 :(得分:1)

您应首先初始化结构的数据成员,因为

current->data  = malloc("passes size here");

对于放置数据,您必须首先对此数据进行类型转换,因为void不是存储类型。 void指针可用于指向任何数据类型。

*(char *)(current->data) = 1;

答案 2 :(得分:1)

正如其他人所说:

scanf("%s",current->data);

在C中未定义。current->data需要指向某处,然后才能在其中存储任何内容。

你应该改为:

  1. 接受来自scanf的输入。
  2. 存储在临时缓冲区中。
  3. 插入链接列表
  4. 打印出最后的整个链表
  5. free()最后的链表。
  6. 我还觉得你当前的void *create函数做得太多了,将代码拆分成不同的函数会更容易,只是为了更容易处理所有的指针操作,插入等等。 / p>

    为了演示这些要点,我前段时间编写了一些代码来执行这些操作,并且已经过修改以帮助您处理代码。它不是最好的代码,但它确实使用了这些有助于您编写代码的点。

    这是:

    #include <stdio.h>
    #include <stdlib.h>
    #include <string.h>
    
    #define MAXSTRLEN 100
    
    typedef struct node {
        void *data;
        struct node *next;
    } node_t;
    
    typedef struct {
        node_t *head;
        node_t *foot;
    } list_t;
    
    list_t *create_list(void);
    node_t *generate_node(void);
    list_t *insert_node(list_t *list, char *data);
    void print_list(list_t *list);
    void free_list(list_t *list);
    
    int
    main(int argc, char *argv[]) {
        list_t *list;
        char data[MAXSTRLEN];
        int user_choice;
    
        list = create_list();
    
        while (1) {
            printf("Enter the data: ");
            scanf("%s", data);
    
            printf("\nType '1' to continue, '0' to exit:\n");
            if (scanf("%d",&user_choice) != 1) {
                printf("Invalid input\n");
                exit(EXIT_FAILURE);
            }
    
            if (user_choice == 1) {
                list = insert_node(list, data);
            } else {
                list = insert_node(list, data);
                break;
            }
        }
    
        print_list(list);
    
        free_list(list);
        list = NULL;
    
        return 0;
    }
    
    /* inserting at foot, you can insert at the head if you wish. */
    list_t
    *insert_node(list_t *list, char *data) {
        node_t *newnode = generate_node();
    
        newnode->data = malloc(strlen(data)+1);
        strcpy(newnode->data, data);
    
        newnode->next = NULL;
        if (list->foot == NULL) {
            list->head = newnode;
            list->foot = newnode;
        } else {
            list->foot->next = newnode;
            list->foot = newnode;
        }
        return list;
    
    }
    
    node_t
    *generate_node(void) {
        node_t *new = malloc(sizeof(*new));
        new->data = NULL;
        return new;
    }
    
    void
    print_list(list_t *list) {
        node_t *curr = list->head;
    
        printf("\nlinked list data:\n");
        while(curr != NULL) {
            printf("%s\n", (char*)curr->data);
            curr = curr->next;
        }
    }
    
    list_t
    *create_list(void) {
        list_t *list = malloc(sizeof(*list));
    
        if (list == NULL) {
            fprintf(stderr, "%s\n", "Error allocating memory");
            exit(EXIT_FAILURE);
        }
    
        list->head = NULL;
        list->foot = NULL;
        return list;
    }
    
    void
    free_list(list_t *list) {
        node_t *curr, *prev;
        curr = list->head;
        while (curr) {
            prev = curr;
            curr = curr->next;
            free(prev);
        }
        free(list);
    }
    

    <强>更新

    还要注意我如何为newnode->data分配内存?

    像这样:

    newnode->data = malloc(strlen(data)+1); //using buffer from scanf
    

    现在这意味着我可以在此指针中存储数据,您的current->data将需要执行类似的操作。

答案 3 :(得分:1)

  

工作代码 - &gt;

void *create(node *current)
{
        node *temp;
        int user_choice;
        while(current){
                printf("\nEnter the data:");
                current->data=(char*)malloc(10*sizeof(char));
                scanf("%s",current->data);
                printf("stored at %p\n",(void*)current->data);
                printf("%s",(char*)current->data);
                printf("\nType '1' to continue, '0' to exit:\n");
                scanf("%d",&user_choice);

                if(user_choice == 1){
                        current->next=(node*)malloc(sizeof(node));
                }
                else{
                        current->next=NULL;
                        temp=current;
                }
                current=current->next;
        }
        return temp;
}

答案 4 :(得分:-1)

请尝试使用此

void *create(node *current)
{
        int user_choice;
        while(true){
                if(current == NULL) {
                   current = (node *)malloc(sizeof(node));
                   current->data = NULL;
                   current->next = NULL;
                }
                printf("\nEnter the data:");
                scanf("%s",current->data);
                printf("stored at %p\n", (void *)current->data);
                printf("%s",current->data);
                //printf("%s",(char*)current->data);
                printf("\nType '1' to continue, '0' to exit:\n");
                scanf("%d",&user_choice);

                if(user_choice == 1){
                        current->next=(node*)malloc(sizeof(node));
                        current=current->next;
                }
                else{
                        current->next=NULL;
                        tail = current;
                        current=current->next;
                        break;
                }
        }
        return current;
}

注意:在我们尝试使用它之前,必须初始化元素(即;必须用一些内存分配)。