C ++-链接列表字符串重复

时间:2018-10-06 09:10:56

标签: c++

更新:这是C ++,而不是C

我正在C语言中创建一个学生链接列表。问题是我在运行它时出现了:

Input:
ID: 1
Name: John
Mark: 10

ID: 2
Name: Jane
Mark: 6

ID: 0 /*to end the list*/

Output:
1   Jane   10
2   Jane   6

您可以看到ID 1在重复ID 2中的名称,如果我有更多ID(例如5 ID),它将在ID 5中重复名称。

这是我的代码

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

struct student {
    int ID;
    char *Name;
    float Mark;
};

struct ttNode {
    struct student data;
    struct ttNode *pNext;
};
typedef ttNode NODE;
struct ttList {
    NODE *pHead, *pTail;
};
typedef ttList LIST;
void CreateEmptyList (LIST &list) {
    list.pHead = list.pTail = NULL;
}
int IsEmptyList(LIST list) {
    if((list.pHead==NULL) && (list.pTail==NULL)) return 1;
    return 0;
}
void AddHead (LIST &list, NODE *pNew) {
    if(IsEmptyList(list))
    {
        list.pHead = list.pTail = pNew;
    }
    else
    {
        pNew -> pNext = list.pHead;
        list.pHead = pNew;
    }
}
void AddTail (LIST &list, NODE *pNew) {
    if (IsEmptyList(list)) {
        list.pHead = list.pTail = pNew;
    }
    else
    {
        list.pTail -> pNext = pNew;
        list.pTail = pNew;
    }
}
NODE *CreateNode (int id, char *name, float mark) {
    NODE *p;
    p = (NODE*) malloc(sizeof(NODE));
    if(p==NULL)
    {
        printf("Allocation error!");
        exit(0);
    }
    p->data.ID = id;
    p->data.Name = name;
    p->data.Mark = mark;
    p->pNext=NULL;
    return p;
}
void Input_AddHead (LIST &list) {
    int id;
    char *name;
    float mark;
    NODE *pNew;
    CreateEmptyList(list);
    do {
        fflush(NULL);
        printf("Input ID (0 to end): ");
        scanf("%d", &id);
        if(id == 0)
            break;
        printf("Input name: ");
        scanf("%s", name);
        printf("Input mark: ");
        scanf("%f", &mark);
        printf("\n");

        pNew=CreateNode(id,name,mark);
        AddHead(list,pNew);
    } while (1);
}
void Output(LIST list)
{
    NODE *p = list.pHead;
    while(p)
    {
        printf("\t%d \t%s \t%f\n ", p->data.ID, p->data.Name, p->data.Mark);
        p = p -> pNext;
    }
}

int main ()
{
    LIST list;
    Input_AddHead(list);
    Output(list);
    return 0;
}

Xcode在此处警告scanf("%s", name);名称未初始化 如果通过将char *name;更改为char *name = nullptr;来遵循Xcode,则程序在输入名称时崩溃。那么这段代码有什么问题。

4 个答案:

答案 0 :(得分:1)

npm install ng2-meta@5.0.0 函数中,语句createNode不复制p->data.Name = name;。要复制name,您将必须使用name库函数。

strcpy

在此之前,您还必须使用char * strcpy ( char * destination, const char * source ); name分配内存。并且分配的内存应该是您传递给它的mallocsizeof

答案 1 :(得分:1)

这是因为您在列表中的name指针被分配为指针。

p->data.Name = name;

因此p->data.Name将始终指向name中的更新值。

尝试如下操作。

p->data.Name = strdup(name);
  

strdup在其中计算所需的空间并分配内存   动态地复制输入字符串并返回新的   分配的指针。另外请注意,strdup不是标准的CC++,因此它不是可移植的。

如果您不想使用strdup,则将内存动态分配给p->data.Name并使用strcpy进行复制。


添加答案来回答代码的主要问题。

void Input_AddHead (LIST &list) {
    .....
    char *name;
    .....
    do {
        .....
        printf("Input name: ");
        scanf("%s", name);

        ......              

        pNew=CreateNode(id,name,mark);
        .....
     } while (1);
}

您看到name尚未分配,引用它会导致未定义的行为。

    scanf("%s", name);

因此,我建议您进行如下更改。

void Input_AddHead (LIST &list) {
    .....
    char *name;
    .....
    do {
        .....
        char line[100];
        printf("Input name: ");
        scanf("%s",line);

        ......              
         name = strdup(line);
        pNew=CreateNode(id,name,mark);
        .....
     } while (1);
}

int如下所示,CreateNode中的大小写指针分配应按原样工作。 无需对p->data.Name进行任何额外分配。

p->data.Name = name;

答案 2 :(得分:1)

首先看问题似乎是

p->data.Name = name;

这应该作为快速解决方法

p->data.Name = strdup(name);

但是使用mallocstrcpy

总是更好

还有很多其他errors仍然可以看到,但我会留给你

您似乎正在将c++ referencesc-pointers混合使用,而且我不确定您的代码是否还在编译,如果它是高度怀疑的话,可能仍然错误的。

答案 3 :(得分:1)

您的程序具有未定义的行为,当您调用name函数时,scanf未初始化:

 void Input_AddHead ( // current codee
      ...
      printf("Input name: ");
      scanf("%s", name);   // <--- name is uninitialized
      printf("Input mark: ");

您应该创建临时缓冲区,在该缓冲区中输入一个字符串,然后复制字符串并将其传递给创建新节点的函数:

void Input_AddHead ( // ... fix
    int id;
    float mark;
    NODE *pNew;
    CreateEmptyList(list);
    do {
        fflush(NULL);
        printf("Input ID (0 to end): ");
        scanf("%d", &id);
        if(id == 0)
            break;
        printf("Input name: ");
        char buf[80];     // create temp buffer
        scanf("%s", buf); // enter data
        char* name = (char*)malloc(strlen(buf)+1); // make copy
        strcpy(name,buf);                          // of string 
        printf("Input mark: ");
        scanf("%f", &mark);
        printf("\n");

        pNew=CreateNode(id,name,mark); // you can pass pointer to unique string