返回一个结构指针

Returning a structure pointer

本文关键字:一个 结构 指针 返回      更新时间:2023-10-16

我是c++新手,需要一些帮助来处理下面的代码。

#include <iostream>
using namespace std;
struct  student {
    string name;
    int age;
    float marks;
};
struct student *initiateStudent(string , int , float);
int main ( ) {
    int totalStudents = 1;
    string name;
    int age;
    float marks;
    cin >> totalStudents;
    student *stud[totalStudents];
    for( int i = 0; i < totalStudents; i++ )  {
        cin >> name >> age >> marks;
        stud[i] = initiateStudent(name,age,marks);
    }
    cout << stud[0]->name;
    return 0;
}
struct student *initiateStudent(string name, int age, float marks)
{
    student *temp_student;
    temp_student->name  = name;
    temp_student->age   = age;
    temp_student->marks = marks;
    return temp_student;
}

我需要在函数initiateStudent中通过传递成员nameagemarks返回指向指针数组stud的结构指针。到目前为止,我知道问题在于当我返回到主文件时,temp_student被销毁了。所以我的问题是如何通过传递结构体的成员,然后将信息返回给指针数组stud来完成。

半回答解释坏习惯:

#include <string>
#include <iostream>
#include <vector>
//using namespace std; often injects subtle bugs. Use with caution
// read more here: 
// http://stackoverflow.com/questions/1452721/why-is-using-namespace-std-considered-bad-practice

struct student
{
    std::string name; // explicit namespacing reduces possibility of unwanted collisions
    int age;
    float marks;
    //added constructor in place of initialization function.
    student(std::string name, int age, float marks):name(name), age(age), marks(marks)
    {
    }
};
int main()
{
    int totalStudents = 1;
    std::string name;
    int age;
    float marks;
    while (!(std::cin >> totalStudents)) // testing input for success
                                         // Needed extra brackets caught by M.M
                                         // teach me to not test even a throw-away example    
    {
        std::cout << "must... have... good... input..." << std::endl; 
        cin.clear(); // clear the error and get rid of any other garbage the user may have input.
        cin.ignore(numeric_limits<streamsize>::max(), 'n');
    }
    //student *stud[totalStudents]; illegal in C++
    std::vector<student *> stud(totalStudents); // using dynamic array instead
    for (int i = 0; i < totalStudents; )// i++ removed
    {
        if (std::cin >> name >> age >> marks) //testing input
        {
            stud[i] = new student(name, age, marks); // using constructor
            i++; // and put here. Only increment if input is valid.
        }
        else
        {
            cin.clear();
            cin.ignore(numeric_limits<streamsize>::max(), 'n');
        }
    }
    std::cout << stud[0]->name;
    for (student * stu: stud) // cleaning up allocated memory
    {
        delete stu; 
    }
    return 0;
}

c++的优点之一是你很少需要自我管理内存。事实上,除了不需要自己清理外,不这样做还有很多好处。

#include <string>
#include <iostream>
#include <vector>

struct student
{
    std::string name;     
    int age;
    float marks;
    student(std::string name, int age, float marks):name(name), age(age), marks(marks)
    {
    }
};
int main()
{
    std::string name;
    int age;
    float marks;
    std::vector<student> stud; // look ma! No pointer!
    while (std::cin >> name >> age >> marks) //exits loop on bad input
    {
        stud.emplace_back(name, age, marks); // building directly in vector
                                             // vector will size itself as needed.
    }
    std::cout << stud[0].name;
    return 0;
}

还有一个警告:>>是用空格分隔的。这意味着当它发现空格(空格、制表符、行尾……)时就会停止,所以"John Jacob jingleheimer - schmidt"的名字将被显示为"John"。然后,>>将尝试将"Jacob"解释为age,这不会很顺利。

简单的解决方案是让initiateStudent()在堆上创建temp_student(使用new):并返回它。请记住,堆分配的内存不会自动释放,所以不要忘记稍后自己释放它。

#include <iostream>
#include <string>
using namespace std;
struct  student {
    string name;
    int age;
    float marks;
};
struct student *initiateStudent(string , int , float);
int main ( ) {
    int totalStudents = 1;
    string name;
    int age;
    float marks;
    cout << "Total student: ";
    cin >> totalStudents;
    cin.sync(); // very very important to not affect the next input (name)
    student* stud = new student[totalStudents];
    for( int i = 0; i < totalStudents; i++ ) 
    {
        cout << "Name: ";
        getline(cin, name);
        cin.sync();
        cout << "age: ";
        cin >> age;
        cout << endl;
        cout << "Marks: ";
        cin >> marks;
        cout << endl;
        cin.sync();
        stud[i] = *initiateStudent(name, age, marks);
    }
    cout << "Student 1: " << stud[0].name << endl;
    delete[] stud;
    stud = NULL;
    return 0;
}
struct student *initiateStudent(string name, int age, float marks)
{
    student *temp_student = new student;
    temp_student->name  = name;
    temp_student->age   = age;
    temp_student->marks = marks;
    return temp_student;
}
相关文章: