2017-01-05 2 views
1

Мне нужно смоделировать периодическую таблицу в C для образовательного программного проекта (это в основном викторина).Выбор случайной структуры ее членами

Я уже создал структуру и объявил все элементы. Теперь я должен написать функцию, которая выбирает один элемент случайным образом.

Это моя структура:

typedef struct{ 
     char name[15]; 
     char shortname[3]; 
     int group; 
     int period; 
}element; 
element hydrogen={"hydrogen", "H", 1, 1}, helium={"Helium", "He", ... 

Я уже пытался объединить их в массив, чтобы генерировать случайный индекс:

element elements[118]; 
elements[1] = {"hydrogen", "H", 1, 1}; 

но только дал мне ошибки :(

Любые идеи?

+0

Вы можете определить массив, например. например: '' таблица элементов [118] = {{"hydrogen", "H", 1, 1}, ...}; '' – BitTickler

+0

Примечание: 'char shortname [3];' слишком мал для [_temporary систематический символ IUPAC_] (https://en.wikipedia.org/wiki/Systematic_element_name), такой как [«Uue»] (https://en.wikipedia.org/wiki/Ununennium). Лучше использовать '#define SHORTNAME_N 4 ... char shortname [SHORTNAME_N];' 'имя символа [15];' тоже выглядит слишком маленьким. – chux

+0

OTOH [«Rutherfordium»] (https://en.wikipedia.org/wiki/Rutherfordium), похоже, является самым длинным именем символа [NAME_N]; 'needing # #define NAME_N (14/* или больше * /) '. – chux

ответ

1

Подход должен работать. Настройте массив структур, затем возьмите index = rand()% 118. Проблема заключается в синтаксисе настройки списка структур. Попробуйте

struct element elements[118] = { 
{"hydrogen", "H", 1, 1}, 
{"helium", "He", 2, 4}, 

    ... etc 
}; 
+0

srand ((unsigned) time (&t));) Он должен назначить time_t t var, чтобы убедиться, что он случайный. – daemondave

0

Вы можете использовать назначенные инициализаторы:

element elements[118] = 
{ 
    [0] = {"hydrogen", "H", 1, 1}, 
    [1] = {"helium", 18, 1}, 
    ... 
}; 

еще лучше, вы можете избавиться от «магических чисел» с помощью перечисления:

typedef enum 
{ 
    ELEMENT_H, 
    ELEMENT_He, 
    ELEMENT_Li, 
    ... 

    NUMBER_OF_ELEMENTS 
} element_t; 

element elements[] = 
{ 
    [ELEMENT_H] = {"hydrogen", "H", 1, 1}, 
    [ELEMENT_He] = {"helium", 18, 1}, 
    ... 
}; 

_Static_assert(sizeof(elements)/sizeof(elements[0]) == NUMBER_OF_ELEMENTS, 
       "Missing elements!"); 

Хотя обратите внимание, что это будет нулевой индекс, в отличие от таблицы Менделеева. Таким образом, вы хотите напечатать номер периодической таблицы, вам придется использовать +1 при печати. (В качестве альтернативы вы можете оставить один элемент мусора в начале массива, но это неаккуратное программирование.)

+0

Почему мы не можем инициализировать массив структуры индивидуально, как задано в вопросе? – Karthick

+0

@Karthick Поскольку вы можете только _initialize_ переменную в одном месте, во время объявления - переменная в этом случае является массивом. Однако вы можете назначать отдельные элементы с помощью сложных литералов и т. Д., Но в этом случае я подозреваю, что массив должен быть 'const', так что это невозможно. – Lundin

+0

Спасибо за объяснение – Karthick

-4

Вы используете менталитет C++ = в пространстве имен C. Это твоя ошибка. Вы находитесь в пространстве имен «C».

:: = оператор, который косвенно копии всех элементов членов от одного к другому, не существует в С.

Скорее, вы должны явно скопировать все члены поэлементно.

Итак:

strncpy (elements[1].name, "hydrogen", strlen("hydrogen")); 
strncpy (elements[1].shortname, "H", strlen("H")); 
elements[1].group = 1; 
elements[1].period = 1; 

будет правильный подход. Встроенная функция или #define упростит ее выполнение и забудет позже.

+0

«= оператор, который неявно копирует все элементы-члены из одного в другой, не существует в C». , вы можете скопировать структуры с помощью оператора = просто, если нет элементов указателя. Вам просто нужно использовать составные литералы. 'element [1] = (element) {" hydrogen ", ...}; 'Не знаю, почему вы создали C++ для начала. – Lundin

+0

Потому что моя интерпретация его замешательства заключалась в том, что он думал на C++. Он не указывал, что статические присваивания были единственным приложением, которое у него могло бы быть. – daemondave

+0

И как упоминалось в моем комментарии , простые старые задания отлично работают в этом случае. Нет необходимости в 'strncpy', которая является функцией, которая не должна использоваться в любом случае по [другим причинам] (http://stackoverflow.com/questio нс/2114896/почему-это-strlcpy-и-strlcat рассмотренный нестабильным). – Lundin

Смежные вопросы