简体   繁体   English

如何正确打印带有人名的链表?

[英]How to print correctly a linked list with name of persons?

I did a code in which I want to print a simple linked list, and the information of the list contain name of person and number phone.我做了一个代码,我想打印一个简单的链表,列表的信息包含人名和电话号码。 Unfortunately, when I print my list have only the name of the last person which I read but the phone numbers were different.不幸的是,当我打印我的列表时,只有我最后阅读的人的名字,但电话号码不同。 I have no idea why my code didn't work.我不知道为什么我的代码不起作用。

So, here is my code所以,这是我的代码

#pragma once

struct Nodd{
   int phone;
   char *name;
   Nodd *next;
};

void InsertList(Nodd *&L,int nr,char *n);
void PrintList(Nodd *&L);


#include <iostream>
#include "Header.h"
using namespace std;
void InsertList(Nodd *&L,int nr, char *n){
    Nodd *p = new Nodd;
    p->name = n;
    p->phone = nr;
    p->next = L;
    L = p;
}

void PrintList(Nodd *&L){
     Nodd *p = L;
     while(p){
       cout << p->name << " " << p-> phone << endl;
       p = p->next;
     }
}

#include <iostream>
#include "Header.h"
using namespace std;

int main(){

    Nodd *L = 0; //L = first element of the linked list
    int nr, i, t;
    char *n;
    n = new char;

    cout <<"Read number of people: ";
    cin >> t;

    for(i = 0; i < t; i++){
        cout << "Name: ";
        cin.ignore(50, '\n');
        cin.getline(n, 50);

        cout << "Phone number: ";
        cin >> nr;
        InsertList(L, nr, n);
    }

    PrintList(L);

    return 0;
}

And what I compiled was:我编译的是:

Read number of people: 2阅读人数:2

Name: Elena
Phone number: 99776244

Name: Andreea 
Phone number: 98776489

............................ …………………………………………………………………………………………………………………………………………………………………………

Andreea  98776489
Andreea  99776244

Can you help me how to fix my code?你能帮我修复我的代码吗?

You have many errors in your code:您的代码中有很多错误:

char *n;
n = new char; // A single dynamic character

And later:然后:

cin.getline(n, 50); UB here

as you can see assigning 50 character to a single character variable so it is an undefined behavior.如您所见,将 50 个字符分配给单个字符变量,因此这是一种未定义的行为。

To correct it:要纠正它:

char* n = new char[50];
  • If you pay deep look to your output what you see:如果您深入查看您的输出,您会看到:

    Andreea 98776489 Andreea 99776244安德烈亚 98776489 安德烈亚 99776244

The same name but the integer values are correct!名称相同但整数值正确! So your inserting nodes function is correct but the problem is about name.所以你的插入节点功能是正确的,但问题在于名称。 Why?为什么?

In insert node you write:在插入节点你写:

p->name=n; // That is not the way you should do it.

Correct it to:更正为:

  p->name = new char[strlen(n) + 1];
  strcpy(p->name, n);

You have to allocate memory for the member name for each node not sharing the same one.您必须为每个不共享同一个节点的成员name分配内存。

  • Also when you're done with dynamic memory you must free up and clean to avoid memory leak:此外,当您使用完动态内存后,您必须释放并清理以避免内存泄漏:

     delete[] n;
  • Add a function to free up memory of all nodes for the member name:添加一个函数来释放成员名称的所有节点的内存:

     void FreeupMemory(Nodd*& L){ Nodd* pTmp = L; while(pTmp){ delete[] pTmp->name; pTmp = pTmp->next; } }

And in main after printing the nodes data free up memory:并在打印节点数据后主要释放内存:

      FreeupMemory(L);
  • What I recommend: As long as C++ offers you many powerful classes and utilities give up using dynamic arrays so here you can use class string , vector .我的建议:只要 C++ 为您提供许多强大的类和实用程序,就可以放弃使用动态数组,因此在这里您可以使用class stringvector It is really good and don't mind about memory leak.这真的很好,不介意内存泄漏。

  • Believe me if your member data name was a string class object you wouldn't get stuck in such error-prone.相信我,如果您的成员数据name是一个字符串类对象,您就不会陷入这种容易出错的问题中。

     struct Nodd{ int phone; std::string name; Nodd *next; }; void InsertList(Nodd *&L,int nr, std::string n){ // your code p->name = n; // ok // ... }

In main:在主要:

    std::string n;
    for(int i(0); i < t; i++){
        std::getline(std::cin, n);
    }

** Also there a bad thing: ** 还有一件坏事:

Why you include the header in itself?为什么要包含标题本身? "recursive inclusion"? “递归包含”?

You can create a header file "header.h" contains only class interface and functions' prototypes and another source file "MyLinkedList.cpp" that includes the header.您可以创建一个仅包含类接口和函数原型的头文件“header.h”和另一个包含头文件的源文件“MyLinkedList.cpp”。 And main.cpp.和 main.cpp。

// header.h
#pragma once

struct Nodd{
   int phone;
   char *name;
   Nodd *next;
};

void InsertList(Nodd *&L,int nr,char *n);
void PrintList(Nodd *&L);
void FreeupMemory(Nodd*&L);


// MyLinkedList.cpp

#include "header.h"
#include <iostream>
using namespace std;


void InsertList(Nodd*& L, int nr, char* n){
    Nodd *p  = new Nodd;
    p->name  = n;
    p->phone = nr;
    p->next  = L;
    L = p;
}

void PrintList(Nodd *&L){
    Nodd* p = L;
    while(p){
        cout << p-> name << " " << p->phone << endl;
        p = p->next;
    }
}

void FreeupMemory(Nodd*& L){
    Nodd* pTmp = L;
    while(pTmp){
        delete[] pTmp->name;
            pTmp = pTmp->next;
    }
}

// main.cpp

#include <iostream>
#include "Header.h"
using namespace std;

int main(){
    Nodd* L = 0; //L = first element of the linked list
    int nr, i, t;
    char* n = new char[50];

    cout << "Read number of people: ";
    cin >> t;

    for(int i = 0; i < t; i++){
        cout << "Name: ";
        cin.ignore(1, '\n');
        cin.getline(n, 50);

        cout << "Phone number: ";
        cin >> nr;

        InsertList(L, nr ,n);
    }

    PrintList(L);
    FreeupMemory(L);
    delete[] n;

    return 0;
}
  • One last thing a good linked list defines functions for adding and deleting nodes as member methods and there should be destructor to free up memory.最后一件事,一个好的链表将添加和删除节点的函数定义为成员方法,并且应该有析构函数来释放内存。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM