我想从文件中按行收集的数据创建一个结构。每一行都需要一个新的结构,并在while循环中访问这些行。在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
}
}
(请详细了解他们何时自动删除,可能没有帮助,但我想知道。谢谢!)
答案 0 :(得分: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对象,并填充其字段,然后将其 copy 推入AllData列表,最后自动销毁该对象(记住列表中仍然存在副本。)
关于何时销毁对象的详细信息
C ++有三种存储方式:静态,自动和动态。
静态存储对象存在于程序的整个生命周期中。在类或函数之外创建的任何对象都是静态的(即全局变量是静态的)。对于使用'static'关键字在类或函数内声明的任何内容也是如此。
动态存储对象是使用关键字“new”(或使用malloc()创建的对象,但这是一个C-ism,除非确实需要,否则通常应该在C ++中避免使用)。动态存储对象是其生命周期由程序员手动管理的对象。动态存储的对象将继续存在,直到您使用关键字“delete”销毁它。请注意,您可以通过指针或引用访问动态存储对象的 方式。如果您没有使用指针或引用,则它不是动态的(但指针/引用也可以引用非动态对象)。
自动存储对象是常规变量:结构和类的成员变量,以及方法和函数中的局部变量(包括参数)。
在运行定义它们的代码行时,会创建函数内定义的自动存储对象。当它们“超出范围”时,它们会自动销毁,也就是说,当它们在其中声明的块终止时。通常,“块”是一组括号:{}。因此,当函数返回时,在函数内部创建的任何东西都会被销毁,同样,当循环到达终点时,无论是否终止或迭代,都会自动销毁在while循环体内创建的任何内容。
定义为类或结构成员的自动存储对象是在创建包含它们的对象时创建的,并在销毁包含它们的对象时销毁。
(我在上面重复使用了术语“对象”,但是相同的规则适用于基本类型,如int,char,bool等)
答案 1 :(得分:1)
你的问题有点不明确。我推断你的意思是每个结构对于每一行都有相同的字段,比如SQL数据库中的列。这意味着不对文件中的每一行都有不同的结构定义。
因此,假设所有结构都具有相同的字段,则工作很容易;只需为您的结构定义一个复制构造函数,然后您可以将它们添加到std::vector
或std::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
的类并正确释放其析构函数中的每个条目,但如果您不知道自己在做什么,则会进入危险区域。)
答案 2 :(得分:0)
C ++中的struct
是一个数据结构,它的整个“结构”(布局,成员,成员类型)是在编译时定义的。
你是否想要类似哈希表(或其他关联/类似地图的数据结构)的东西,你在文件的每一行中有一个这样的结构,比如一个数组?
答案 3 :(得分:0)
在C ++中没有匿名类型这样的东西。您必须显式定义行结构,然后必须定义表示行集合的数据结构。