C ++ создание и сбор структур в цикле - PullRequest
1 голос
/ 31 августа 2009

Я хочу создать структуру из данных, собранных строкой из файла. Каждая строка требует новой структуры, и строки доступны в цикле 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
  }
 }

(уточните, когда они автоматически удаляются, это, вероятно, не поможет, но я хотел бы знать. Спасибо!)

Ответы [ 4 ]

9 голосов
/ 31 августа 2009

Ваш 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-ism, которого, как правило, следует избегать в C ++, если в этом нет особой необходимости). Объекты динамического хранения - это объекты, временем жизни которых управляет программист вручную. Динамически сохраняемый объект будет существовать до тех пор, пока вы не уничтожите его с ключевым словом «удалить». Обратите внимание, что only способ доступа к динамически хранимому объекту - через указатель или ссылку. Если вы не используете указатель или ссылку, он не является динамическим (но указатель / ссылка также может ссылаться на нединамический объект).

Объекты автоматического хранения - это ваши обычные переменные: переменные-члены структур и классов и локальные переменные (включая параметры) в методах и функциях.

Объекты автоматического хранения, определенные внутри функций, создаются при запуске строки кода, которая их определяет. Они автоматически уничтожаются, когда они «выходят за рамки», то есть когда блок, в котором они объявлены, завершается. В общем, «блок» - это набор фигурных скобок: {}. Таким образом, все, что создано внутри функции, уничтожается, когда функция возвращается, и аналогичным образом, все, что создается внутри тела цикла while, автоматически уничтожается, когда цикл достигает своего конца (независимо от того, завершается он или повторяется снова).

Объекты автоматического хранения, определенные как члены классов или структур, создаются при создании объекта, который содержит их в качестве членов, и уничтожаются, когда объект, содержащий их в качестве членов, уничтожается.

(я неоднократно использовал термин «объект» выше, но те же правила применяются к фундаментальным типам, таким как int, char, bool и т. Д.)

1 голос
/ 31 августа 2009

Ваш вопрос немного неясен относительно того, что вы спрашиваете. Я предполагаю, что вы имеете в виду, что каждая структура имеет одинаковые поля для каждой строки, как столбцы в базе данных SQL. Это означает, что у вас нет отдельного определения структуры для каждой строки в файле.

Итак, при условии, что все ваши структуры имеют одинаковые поля, работа проста; просто определите конструктор копирования для вашей структуры, а затем вы можете добавить их в std::vector или std::list или в собственную реализацию массива / списка / deque / что угодно.

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 голосов
/ 31 августа 2009

В C ++ нет такого понятия, как анонимный тип. Вы должны явно определить структуру линии, а затем определить структуру данных, которая представляет коллекцию строк.

0 голосов
/ 31 августа 2009

A struct в C ++ - это структура данных, вся "структура" которой (макет, элементы, типы элементов) определяется во время компиляции.

Возможно, вам нужно что-то вроде хеш-таблицы (или другой ассоциативной / картографической структуры данных), где у вас есть одна из этих структур на строку файла, например, в массиве?

...