2009-08-31 251 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++匿名类型。您必须明确定义行结构,然后您必须定义表示行集合的数据结构。