我正在尝试使用 vector
创建一个结构指针列表。我的结构包含一些字段,如
#include<stdio.h>
#include<stdlib.h>
#include<vector>
#define MAX 100
struct Student {
char* name,
*phoneNum,
*address
};
我有一个实用函数可以帮助初始化结构指针
struct Student* newStudent() {
struct Student* pStudent = NULL;
pStudent = (struct Student*)malloc(sizeof(struct Student));
pStudent->name = (char*)malloc(MAX * sizeof(char));
pStudent->phoneNum = (char*)malloc(MAX * sizeof(char));
pStudent->address = (char*)malloc(MAX * sizeof(char));
return pStudent;
}
插入函数就像
void insert(vector<Student*> &listStudents, Student* pStudent) {
printf("name: "); scanf("%s\n" , pStudent->name);
printf("phone number: "); scanf("%s\n", pStudent->phoneNum);
printf("address: "); scanf("%s\n", pStudent->address);
listStudents.push_back(pStudent);
printf("inserted OK!\n");
printf("Size: %lu\n", listStudents.size());
}
和显示功能
void display(vector<Student*>& listStudents) {
printf("total students: %lu\n", listStudents.size());
for (int i = 0; i < listStudents.size(); i++) {
printf("Student %d\n", i+1);
printf("name: %s\n", listStudents[i]->name);
printf("phone number: %s\n", listStudents[i]->phoneNum);
printf("address %s\n", listStudents[i]->address);
}
}
这是我的主要功能
int main() {
Student* pStudent = newStudent();
vector<Student*> listStudents;
while(true) {
int op1;
printf("\n1. input\n2. output\n3. search\n4. erase\n5. end\n");
printf("option: ");
scanf("%d", &op1);
switch(op1) {
case 1:
insert(listStudents, pStudent);
break;
case 2:
display(listStudents);
break;
default:
printf("invalid option!\n");
break;
}
}
free(pStudent);
}
当我尝试在每个字段中插入一些信息时。挺好的但是当我展示它时 出去。结果是重复的。例如:
insert
:
Student 1:
name: A
phone number: 010...
address: xyz
Student 2:
name: B
phone number: 011...
address: zyz
display
结果是
Student 1:
name: B
phone number: 011...
address: zyz
Student 2:
name: B
phone number: 011...
address: zyz
这是怎么回事??
答案 0 :(得分:2)
你的问题是你有一个学生类的实例,你写了它。在 C++ 中,类通常具有值语义。你通常不管理自己的记忆。这是一个更惯用的实现:
#include <iostream>
#include <string>
#include <vector>
class Student final {
private:
std::string m_name;
std::string m_phoneNum;
std::string m_address;
public:
Student(std::string name, std::string phoneNum, std::string address)
: m_name(std::move(name)),
m_phoneNum(std::move(phoneNum)),
m_address(std::move(address)) {}
auto& Name() const noexcept { return m_name; }
auto& PhoneNumber() const noexcept { return m_phoneNum; }
auto& Address() const noexcept { return m_address; }
};
Student GetStudent() {
std::string name, num, addr;
std::cout << "Name: ";
std::cin >> name;
std::cout << "Phone nnumber: ";
std::cin >> num;
std::cout << "Address: ";
std::cin >> addr;
Student st(std::move(name), std::move(num), std::move(addr));
return st;
}
int main() {
std::cin.exceptions(std::istream::failbit | std::istream::badbit);
std::vector<Student> vec;
vec.push_back(GetStudent());
vec.push_back(GetStudent());
vec.push_back(GetStudent());
for (auto const& elm : vec) {
std::cout << "Name: " << elm.Name() << "\nPhone: " << elm.PhoneNumber()
<< "\nAddress: " << elm.Address() << '\n';
}
}
这也解决了许多其他错误:
scanf
调用可能会发生缓冲区溢出lu
不是 size_t
nullptr
之后不检查 malloc
printf
要么被显式刷新,要么在调用 '\n'
之前以 scanf
结束。可能还有更多。
答案 1 :(得分:0)
正如@WhozCraig 在他的评论中提到的,您正在更改相同的结构指针。您必须每次分配不同的结构指针。你的主要功能应该是这样的,
int main() {
vector<Student*> listStudents;
while(true) {
int op1;
printf("\n1. input\n2. output\n3. search\n4. erase\n5. end\n");
printf("option: ");
scanf("%d", &op1);
switch(op1) {
case 1: {
Student* pStudent = newStudent();
insert(listStudents, pStudent);
break;
}
case 2:
display(listStudents);
break;
default:
printf("invalid option!\n");
break;
}
}
for (const auto& pointers: listStudents)
free(pointers)
}
每次用户输入 1 时,您必须分配一个新的结构体指针。