2009-08-31 246 views
1

我想從文件中按行收集的數據創建一個結構體。每一行都需要一個新的結構,並且這些行在while循環中被訪問。在C#中,我通過創建匿名結構並將它們添加到結構列表中來完成此操作。 C++似乎不允許匿名結構。我嘗試用增量變量命名它們,但這不起作用,因爲變量名是從字面上理解的 - 無論如何,我不希望被迫使用這種方法,因爲我討厭不相關的名稱。我想我可以通過一個獨特的屬性命名該結構,但顯然,我寧願使用一個屬性。 。 。屬性。此外,如果它們不一定都是唯一的呢?C++在循環中創建和收集結構體

有人可以提出一些建議或解釋我失蹤的東西嗎?

謝謝!

在C#

(僞:

public static List<Referral> Referrals = new List<Referral>(); 

//in loop: 
var NewReferral = new Referral(referringURL.Trim(), referringWords.Trim().ToLower() , 1); 
if (NewReferral.URL == referringURL.Trim()) {Referrals.Add(NewReferral); 
在C

++:

list<CollectedData> AllData; 

ifstream myFile("test_data.txt"); 
if (myFile.fail()) {cout << "Error opening file"; return 0;} 
else 
{ 
    cout << "File opened... \n"; 
    while(getline(myFile, line)) { 
    struct CollectedData; 
         //add property values 
         //add struct to struct list 
    } 
} 

(請不要進入,當他們自動刪除,它可能不會是有幫助的細節,但我)

+1

您可以發佈一些代碼(無論是您的原始C#實現還是您的C++嘗試),以便我們能夠掌握您正在嘗試做什麼?我一點都不清楚。 – 2009-08-31 00:49:56

+0

您在這裏不使用任何匿名類型。 – pingw33n 2009-08-31 00:58:33

回答

9

你的C++外觀走在正確的軌道上,除了兩件事。一,你必須定義一個CollectedData結構某處的形式,和兩個你必須給一個名稱,你的結構變量:

例如,如果你定義了CollectedData結構像這樣

struct CollectedData { 
    int field1; 
    std::string field2; 
    bool field3; 
    // etc 
}; 

然後在你的內循環就可以通過循環做到這一點

while(getline(myFile, line)) { 
       CollectedData lineData; 
       //add property values 
       lineData.field1 = /*whatever*/; 
       lineData.field2 = /*whatever*/; 
       lineData.field3 = /*whatever*/; 
       //add struct to struct list 
       AllData.push_back(lineData); 
     } 

每次創建一個新的CollectedData對象,其字段填寫,然後複製它被推入ALLDATA列表,然後鰭盟友的對象被自動銷燬(記住副本仍然存在於列表中)。

詳細介紹一下當對象被銷燬

C++有三類存儲:靜態,自動和動態。

靜態存儲對象存在於程序的整個生命週期中。任何在類或函數之外創建的對象都是靜態的(即全局變量是靜態的)。對於使用'static'關鍵字在類或函數內部聲明的任何內容也是如此。動態存儲對象是使用關鍵字'new'(或用malloc()創建的對象,但這是一個通常應該在C++中避免的C-ism,除非真的必要)。動態存儲對象是其生命週期由程序員手動管理的對象。動態存儲的對象將繼續存在,直到使用關鍵字「delete」銷燬它。請注意,只有方式可以通過指針或引用訪問動態存儲的對象。如果不使用指針或引用,它不是動態的(但指針/引用也可以引用非動態對象)。自動存儲對象是常規變量:結構和類的成員變量,以及方法和函數中的局部變量(包括參數)。

在定義它們的代碼行運行時,會在函數內定義自動存儲對象。當它們「超出範圍」時,它們會自動銷燬,也就是說,當它們在內部聲明的塊終止時。通常,「塊」是一組大括號:{}。因此,函數內部創建的任何內容都會在函數返回時被銷燬,同樣,當循環體內部創建的任何內容在循環結束時自動銷燬(不管它是終止還是迭代)。

定義爲類或結構成員的自動存儲對象是在包含它們作爲成員的對象被創建時創建的,並且在包含它們作爲成員的對象被銷燬時被創建並被銷燬。

(我用的術語「對象」反覆以上,但同樣的規則也適用於基本類型如int,焦炭,布爾等)

+0

+1爲清楚起見。動態和堆棧分配的區別也在這裏描述:http://stackoverflow.com/questions/599308/proper-stack-and-heap-usage-in-c – Crashworks 2009-08-31 01:38:06

0

A struct在C++中是一個數據結構,它的整個「結構」(佈局,成員,成員類型)被定義在編譯時。

您可能想要像hashtable(或其他關聯/ map-like數據結構)的東西,而不是每個文件的行中有一個這樣的結構,比如數組?

1

你的問題有點不清楚你問什麼。我推斷你的意思是每個結構對於每一行都有相同的字段,如SQL數據庫中的列。這意味着你不對有一個不同的結構定義文件中的每一行。

所以,假設你所有的結構都有相同的字段,這個工作很容易;只需爲你的結構定義一個拷貝構造函數,然後你可以將它們添加到std::vectorstd::list或你自己的array/list/deque/whatever的實現中。

struct mystruct 
{ 
    int a,b,c; 
    // has default (shallow-copy) constructor, coz that's fine for integral types... 
} 

void readfromfile(YourFileClass *pFile, /* etc.. */) 
{ 
    mystruct temp; 
    std::list<mystruct> result; 
    // read each line into the temp struct one at a time, add to a list 
    while (pFile->ReadNextFileLineIntoStruct(&temp)) 
    { 
     result.push_back(temp); 
    } 
    // result has a linked list of data... 
} 

您也可以new了通過循環每次你的結構的一個實例,並添加指針這些結構的列表(Smashery建議),但要注意,這些對象不會當清單被刪除時,您可以自由地清除 - 當您完成清單時,您需要遍歷整個清單並致電delete,否則您將無法挽回地泄漏內存。

(您也可以從std::list繼承和適當釋放了在其析構函數中的每個條目的一類,但這種進入危險地帶,如果你不知道自己在做什麼。)

0

有沒有這樣的事情在C++匿名類型。您必須明確定義行結構,然後您必須定義表示行集合的數據結構。