簡體   English   中英

如何讀取.txt文件,轉換為c ++中的繼承對象?

[英]How can I read .txt files, to inherited objects in c++?

我正在做一項作業,我必須在c ++中為體育組織創建一個數據庫,而無需使用STL(我創建了自己的列表和String)。 數據庫將數據保存在一個雙鏈表中,其中除了節點之外,還有數據,即團隊。 當然,不僅有一種類型的團隊,目前有三類。 這些對象,繼承了team對象。 除了讀取文本文件並由此創建對象之外,我已經使所有工作都可以進行。

我已經嘗試過創建一個標記,這是程序將要讀取的第一條信息,它將決定需要創建三個類中的哪一個,然后讀取其他數據,以創建新對象,然后將其放入在雙向鏈接列表的末尾。 不幸的是,它不起作用,而是什么也不做,繼續整個程序,就像什么也沒發生一樣。

void hozzaad(ListaElem *s, team *data) { ///adding to the end
        ListaElem *iter = s;
        while (iter->kov=NULL)
        {
            iter = iter->kov;
        }
        ListaElem *uj = new ListaElem(data);
        uj->elozo = iter;
        iter->kov = uj;
    }

    void listaz(ListaElem *s) { //print out all that is in the list
        if (s == NULL) {
            std::cout << "Ures lista" << std::endl;
            return;
        }
        ListaElem *iter = s;
            while (iter!=NULL)
            {
                iter->adat->kiirt(std::cout);
                iter = iter->kov;
        }
    }

void listament(ListaElem *s, const char *a) { //this one creates the file
        std::ofstream file;
        file.open(a);
        ListaElem *iter = s;
        if (file.is_open()) {
            while (iter != NULL) {
                file << iter->adat->Getclub()<< "\n";
                file << iter->adat->Getname() << "\n" << iter->adat->Getmember()<< "\n";
                if (iter->adat->Getclub() == 1) {
                    file << iter->adat->Getsupport() << "\n";
                }
                if (iter->adat->Getclub() == 2) {
                    file << iter->adat->Getpompom() << "\n";
                }
                if (iter->adat->Getclub() == 3) {
                    file << iter->adat->Getname1() << "\n" << iter->adat->Getname2() << "\n";
                }
                iter = iter->kov;
            }
        }
        else
        {
            std::cout << "Nem tudom kinyitni a file-t";
        }
        file.close();
        return;
    };

void test4() {                  // the basic test 
    Handball c("Kezes HC", 21, 50000);
    team adat("", 0);
    ListaElem *egyik = new ListaElem(&adat);
    hozzaad(egyik,&c);
    ListaElem *uj = new ListaElem(&adat);
    listament(egyik, "test.txt"); 
    std::ifstream file;
    file.open("test.txt");
    if (!(file.is_open())) {
        std::cout << "hiba\n";
        return;
    }
    int micsoda;
    while (file >> micsoda);
    {
        if (micsoda == 1) {
            String beolvas("");
            int m;
            int d;
            getline(file, beolvas);
            file >> m;
            file >> d;
            Handball ujh(beolvas, m, d);
            hozzaad(uj, &ujh);
            beolvas = "";
        }
        if (micsoda == 2) {
            String fbeolvas("");
            int fm;
            String e1("");
            String e2("");
            getline(file, fbeolvas);
            file >> fm;
            getline(file, e1);
            getline(file, e2);
            football ujh(fbeolvas, fm, e1, e2);
            hozzaad(uj, &ujh);
        }
        if (micsoda == 3) {
            String bbeolvas("");
            int bm;
            int bd;
            getline(file, bbeolvas);
            file >> bm;
            file >> bd;
            Basketball ujh(bbeolvas, bm, bd);
            hozzaad(uj, &ujh);
        }
    }
    std::cout << "OK" << std::endl;
    listaz(uj);
    file.close();
    std::cout << "OK" << std::endl;
}


test4() expects to go out like:

還可以Kezes HC 21 50000還可以

將代碼縮短到絕對必要的位置:

if (micsoda == 1)
{
    Handball ujh;
    hozzaad(uj, &ujh);
} // at this point in code, your object ujh runs out of scope!!!

當對象超出范圍時,它會被銷毀(您會注意到是否在類的析構函數中添加了一些輸出語句...),並且指向該對象的任何指針都將變為無效; 特別是,列表中的那些將變得無效(可以說是懸空的指針-或引用,可能會發生相同的情況)。 現在使用它們會導致不確定的行為 -這意味着任何事情都可能發生。 如果您不走運(或視情況而定走運),您的程序甚至會崩潰。

請注意,由於缺少代碼的重要部分,我假設您僅將指向對象的指針存儲在ListaElem類中,但是很可能,因為要存儲的類是多態的...

但是,您需要的是對象的壽命比程序在if塊中的壽命更長。 假設我們針對現實生活中的場景,那么僅將對象移出if子句是不可能的,因為我們可能需要多個同類型的單個對象。 因此,您將動態創建對象。 但是,那么您還必須處理內存管理和所有權問題。 處理內存管理部分最容易的方法是使用智能指針。 所有權? 好吧,對我來說,假設列表是對象的唯一所有者似乎很合理,因此您可以:

class ListElem
{
    std::unique_ptr<Team> m_data;
public:
    ListElem(std::unique_ptr<Team> data) // accepting a unique_ptr already here indicates
                                         // clearly that the item will grab ownership
        : m_data(std::move(data)) // unique_ptr is only movable, not copiable!
    { }
}

然后,您可以將上面的代碼更改為:

if (micsoda == 1)
{
    int n, m; // sample data
    hozzaad(uj, std::make_unique<Team>(n, m); // arguments are passed directly to
                                              // the constructor of class Team
}

好的,您不允許使用STL。 那么您將自己編寫智能指針以及make_uniquemove模板函數(就像您對list和string所做的那樣)。 在cppreference上,您可以找到一個示例實現,例如std::make_unique 不要只是復制/粘貼代碼,而是先了解它,最好自己重新編寫它,否則您將不會學任何東西(上面的代碼也是如此)。 或者,您可能會問您的老師,她/他是否在智能指針的STL方面例外。

最終建議:在連續內存上進行操作通常比在整個系統RAM上可能分布的內存上進行操作要快得多。 因此,您可以考慮重新實現std::vector而不是std::list

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM