1

I have to model the periodic table in C, for an educational software project (It's basically a quiz).

I already created a struct and declared all the elements. Now I have to write a function that chooses one element randomly.

This is my struct:

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

I already tried to combine them in an array, to then generate a random index:

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

but that just gave me errors :(

Any ideas?

  • You can define an array, e.g. like this: ``element table[118] = { {"hydrogen", "H", 1, 1}, ... };`` – BitTickler Jan 05 '17 at 15:08
  • Note: `char shortname[3];` is too small for [_temporary systematic IUPAC symbol_](https://en.wikipedia.org/wiki/Systematic_element_name) such as ["Uue"](https://en.wikipedia.org/wiki/Ununennium). Better to use `#define SHORTNAME_N 4 ... char shortname[SHORTNAME_N ];` `char name[15];` looks small too. – chux - Reinstate Monica Jan 05 '17 at 15:41
  • OTOH ["Rutherfordium"](https://en.wikipedia.org/wiki/Rutherfordium) does seem to be the longest `char name[NAME_N];` needing `#define NAME_N (14 /* or more */)`. – chux - Reinstate Monica Jan 05 '17 at 15:56

3 Answers3

1

The approach should work. Set up an array of structs, then take index = rand() % 118. Your syntax for seting up the list of structures is the problem. Try

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

  ... etc 
};
Malcolm McLean
  • 6,258
  • 1
  • 17
  • 18
0

You can use designated initializers:

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

Better yet, you can get rid of the "magic numbers" by using an enum:

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!");

Though please note that this will be zero-indexed, unlike the periodic table. So you you want to print the periodic table number, you'll have to use +1 when printing. (Alternatively you could leave one garbage item at the start of the array, but that is sloppy programming.)

Lundin
  • 195,001
  • 40
  • 254
  • 396
  • Why cant we initialise the structure array individually as asked in question? – Karthick Jan 05 '17 at 16:30
  • @Karthick Because you can only _initialize_ a variable at one single place, during declaration - the variable in this case being the array. You can however runtime assign individual items by using compound literals etc, but in this case I suspect the array should be `const` so that's not possible anyhow. – Lundin Jan 05 '17 at 19:23
  • Thanks for the explanation – Karthick Jan 06 '17 at 13:01
-4

You are using a C++ = operator mentality inside a C name space. That is your mistake. You are in namespace "C".

::= operator that implicitly copies all member elements from one to another does not exist in C.

Rather, you must explicitly copy all members element by element.

So:

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

would be the right approach. An inline function or #define would make it easier to execute and forget later.

daemondave
  • 309
  • 2
  • 12
  • "= operator that implicitly copies all member elements from one to another does not exist in C" Sure it does, you can copy structs with the = operator just fine, as long as there are no pointer members. You'll simply have to use compound literals. `element[1] = (element){"hydrogen", ...};`. Not sure why you brought up C++ to begin with. – Lundin Jan 05 '17 at 15:15
  • Because my interpretation of his confusion was that he was thinking in C++. He didn't specify static assignments were the only application he might have. – daemondave Jan 05 '17 at 15:19
  • And as mentioned in my comment, plain old assignments work just fine in this case. There is no need for `strncpy`, which is a function that shouldn't be used anyway, for [other reasons](http://stackoverflow.com/questions/2114896/why-are-strlcpy-and-strlcat-considered-insecure). – Lundin Jan 05 '17 at 15:26