基于用户输入的c ++对象的动态初始化

时间:2016-10-02 16:46:30

标签: c++ database class object

对不起上一个问题

好的。我的项目是使用c ++为大学创建和运行数据库

我必须使用USN作为唯一学生编号来访问数据库:

所以我写了以下程序:

#include<iostream>
# include<conio.h>
#include<iomanip>
#include<string.h>
#include<stdlib.h>

int checkinarray(char[],char*);
using namespace std;

class student
{

private :

    int sem;
    float cgpa;
    char password[11];
    char passwordtrial[11];
    void readdata();
    void checkpassword();
    void createpassword();

public :
    char name[50];
    int roll;
    void printdata();
    char USN[11];
    static int number;
    void opendatabase();
    void firsttime();
public:
    student(char n[50]="NONE")
    {
        number++;
        roll=number;
        cout<<endl<<"New record under the name of "<<n<<" has been created !"<<endl;
        cout<<"Roll number set for new student as : "<<roll<<endl;
        cout<<"Use this Roll number for further usage"<<endl<<endl;
    };

};

void student::opendatabase()
{
    int ch;
    cout<<"Enter your name:"<<endl;
    cin>>name;
    cout<<"Enter your password"<<endl;
    cin>>passwordtrial;
    if(!strcmp(passwordtrial,password))
    {
        cout<<"Do you want to read or write";
        cin>>ch;
        switch(ch)
        {
        case 0 :
            readdata();
            break;

        case 1 :
            printdata();
            break;
        }

    }
    else
        cout<<"Try Again";

};
void student::readdata()
{
    cout <<endl<<"Enter the name of the student : ";
    cin >> name;
    cout <<endl<<"Enter the semester of the student : ";
    cin >> sem;
    cout <<endl<<" Enter the cgpa of the student : ";
    cin >> cgpa;
};

void student :: printdata()
{
    cout << "The name is : " << name << endl;
    cout << "The sem is : " << sem << endl;
    cout << "The roll is : " << roll << endl;
    cout << "The cgpa is : " << cgpa << endl;

}
void student::firsttime()
{
    cout<<"Enter your name :";
    cin>>name;
    cout<<"Hey "<<name<<" Welcome to DBMS "<<endl;
    createpassword();
};

void student::createpassword()
{
    cout<<"Please enter your 6 character password.. :  ";
    cin>>password;
    cout<<"Please Input your Data here.... :" ;
    readdata();
};
int student::number=0;
int main()
{
    enum status {existing,newacc,exit};
    enum functi{read,update};
    char entry1[40];
    char entry[10];
    char usn[15];
    char  a[1000][15];
    char n[40];
    int i,j=0,k;
    int s=2;
    cout<<endl<<"WELCOME TO COLLEGE NAME"<<endl<<"Press enter to access Database...";
    getch();
    cout<<endl<<"Welcome to the Main Page of our Database : "<<endl;
    while(1)
    {//User option
        cout<<endl<<"Do you want to access an old entry : "<<endl<<"OR"<<"Create a NEW entry : ";
        cin>>entry1;
        if(!strcmp(entry1,"old"))
            s=existing;
        else if(!strcmp(entry1,"new"))
            s=newacc;
        else
            s=exit;
        switch(s)
        {

            case existing:
                            {
                                i=1;
                                break;
                            }

            case newacc:
                            {   i=1;
                                cout<<endl<<"Enter your usn : "<<endl;
                                cin>>usn;
                                strcpy(a[j],usn);
                                j++;
                                strcpy(n,usn);
                                cout<<n;
                                student usn(n);
                                usn.firsttime();     //Start here!! use i to go to next loop or stay in this loop,,change name entry to usn
                                break;
                            }


            default :{cout<<"Error Input";i=0;break;}
        }

         if(i)
            continue;

            cout<<endl<<"What do u want to do??"<<endl<<"Read Entries "<<endl<<"Update entries";
            cin>>entry;
            if(!strcmp(entry,"read"))
                s=read;
            else if(!strcmp(entry,"update"))
                s=update;
            else
                s=exit;
            cout<<endl<<"Enter your usn : "<<endl;
            cin>>usn;
            if(checkinarray(a[15],usn))
            {
               switch(s)
                {

                        case read:{
                                        usn.printdata();
                                        break;
                                  }


                        case update:{
                                        usn.firsttime();
                                        break;
                                   }


                        default :
                                    cout<<"Are you sure you want to exit?"<<endl<<"Press 0 to exit"<<endl<<"to back to menu press 1";
                                    cin>>k;
                                    break;

                        }
                if(!k)
                    break;

            }

            else cout<<"Invalid Roll number try again!";
    }


}

int checkinarray(char a[][15],char b[])
{
    int len;
    //Finding the length of the string :
    len=(sizeof(a)/sizeof(a[0]));
    //Checking Conditions for roll number:
    for(int k=0;k<len;k++)
    {
        if(strcmp(a[k],b))
            return 1;//stringcompare!!

    }
    return 0;
}

好的,所以当我运行这个时,我得到以下错误:

请求'usn'中的成员'printdata',这是非类型'char [15]' 和

请求'usn'中的成员'firsttime',这是非类型'char [15]'

因此,请通过建议基于用户输入创建和调用对象的不同方法来帮助我克服此错误

1 个答案:

答案 0 :(得分:0)

OP的问题可以简化为以下示例:

#include<iostream>
#include<string.h>

using namespace std;

class student
{
public:
    student(char n[50])
    {
    }
};
int main()
{
    char usn[15];
    char n[40];
    {
        cin >> usn;
        strcpy(n, usn);
        student usn(n);
    }
    usn.printdata();
}

这就是Minimal, Complete, and Verifiable example的含义。不是一切,而是重现问题所需的一切。 MCVE的美妙之处在于它将问题简化到可以在屏幕上并且可能在大脑中的所有部分,使其易于分析和测试。

注意事项:

有两个名为usn

的变量
char usn[15];

main内的自动变量。它仅在main内可见,并将在main

结束时到期
student usn(n);

main内匿名块内的自动变量。它仅在此块中可见,并将在块结束时到期。

注释这个块以更好地解释发生的事情,我们得到

{
    cin >> usn; // uses char usn[15];
    strcpy(n, usn);
    student usn(n); // declares a new variable named usn that replaces char usn[15];for the remainder of this block
} // student usn(n); ends right here and is destroyed.
usn.printdata(); //uses char usn[15]; which has no printdata method.

那么我们该如何解决这个问题呢?

  1. student usn(n);的范围必须更广。
  2. 这两个变量中的一个必须更改名称,因为一旦student usn(n);范围更广,它将与char usn[15];碰撞
  3. 让我们快速尝试一下。

    int main()
    {
        char usn[15];
        char n[40];
        student stud(n);
        {
            cin >> usn;
            strcpy(n, usn);
        }
        stud.printdata();
    }
    

    不可能,因为n中没有我们可以制作stud的数据。至少不是这个最小的例子。

    int main()
    {
        char usn[15];
        char n[40];
        student * stud;
        {
            cin >> usn;
            strcpy(n, usn);
            stud = new student(n);
        }
        stud->printdata();
        delete stud;
    }
    

    通过动态分配stud来解决这个问题,使其不再受大括号的限制。不幸的是,这确实会带来一些额外的内存管理问题。必须删除stud。添加了delete,但如果printdata引发异常并且跳过delete stud;该怎么办?

    int main()
    {
        char usn[15];
        char n[40];
        std::unique_ptr<student> stud;
        {
            cin >> usn;
            strcpy(n, usn);
            stud.reset(new student(n));
        }
        stud->printdata();
    }
    

    std::unique_ptr takes care of that.但是......整个数据库的事情怎么样?为什么不将stud存储在列表中?

    int main()
    {
        char usn[15];
        char n[40];
        std::vector<student> studs;
        {
            cin >> usn;
            strcpy(n, usn);
            studs.emplace_back(n); // or studs.push_back(student(n));
        }
        for (student & stud: studs)
        {
            stud.printdata();
        }
    }
    

    std::vector solves both problems at once.