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

storing and printing string in void pointer

我写了一个链表程序,将数据成员存储为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 的正确参数应该是什么?


working code after incorporating points given in answers...

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;
}

在您的代码中,

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

试图使用一个统一的指针,它调用 undefined behavior.

您需要遵循以下任一方法,

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

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

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

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

喜欢

*(char *)(current->data) = 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;
}

注意:在我们尝试使用该元素之前,必须对其进行初始化(即,必须为其分配一些内存)。

正如其他人所说:

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

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

你应该改为:

  1. 接受来自 scanf 的输入。
  2. 存储在临时缓冲区中。
  3. 插入链表
  4. 最后打印出整个链表
  5. free()链表在最后。

我也觉得你现在的void *create函数做的太多了,把你的代码拆分成不同的函数会更容易,只是为了更容易处理所有的指针操作,插入等.

为了证明这些要点,我刚才写了一些代码来做这些事情,并且已经过修改以帮助您处理代码。它不是最好的代码,但它确实使用了这些可以帮助您编写代码的要点。

这里是:

#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 将需要做类似的事情。

working code-->

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;
}