While you have one answer, I would suggest taking a hard look at the first comment posted following your question. Regardless how you slice it, you will have to parse the user input in the form of a string. While it may seem daunting to parse something like "Li3Co4CO2"
to get the atomic weight for each element, multiply it by the correct multiplier and keep a running sum, it can be done with 2 pointers and a nested while loop.
Take for example your user input in argv[1]
and assign it to pointer p
:
char *p = argv[1];
All you need now is a while
loop to check each character in the string:
while (*p) {
Within the loop, all you will need to do is to identify each element a Capital letter followed by any lower case and a terminating digit (if any) before the next Cap or the null-terminating character (end of string). So assign an end-pointer say ep
and work down the string with a nested while
loop. (we'll add a multiplier to hold the digit, and a symbol length for use later) We skip the first character in p
, (char *ep = p + 1;
), so we will initialize the symbol length to 1
as well (the multiplier always starts at 1):
char *ep = p + 1; /* end pointer */
char m = 1; /* multiplier */
size_t symlen = 1; /* symbol len */
...
/* for each char in p until next CAP */
while (*ep && (*ep < 'A' || 'Z' < *ep)) {
/* if digit */
if ('0' <= *ep && *ep <= '9')
m = *ep - '0'; /* set multiplier */
else
symlen++; /* increment len */
ep++;
}
You now have all the information you need to copy/search for the symbol and then add the weight to a running sum. To finish isolating the symbol, you can simply use your symlen
along with strncpy
to copy the symbol to a temporary array/string:
char srchsym[8] = {0}; /* search sym */
strncpy (srchsym, p, symlen);
srchsym[symlen] = 0; /* null-terminate */
(the manual null-termination is technically not needed since you initialized srchsym[8] = {0};
, but it is a good habit)
Now all that is left is to search for srchsym
within your periodic table (array of structs) and return a pointer to the element of the array that corresponds to element that matches your search symbol (the atomic symbol). Once you have a pointer to the data in your periodic table, keeping the running sum in wt
is as simple as:
wt += (float)m * ptp->atwt;
(where ptp
- pointer to periodic table and the element of the stucture atwt
is the atomic weight.) With the calculation for the first element done, simply advance your pointer p
to the next Cap in the string, and repeat:
p = ep;
}
When done, you can print your results:
printf ("\n %s (atomic weight) : %.3f\n\n", argv[1], wt);
If you like, you can also have the loop print out each element it is adding to the sum as it is returned by your search with srchsym
. An example for the hypothetical "Li3Co4CO2"
would be:
$ ./bin/ptable Li3Co4CO2
element : Lithium
symbol : Li
atomic num : 3
atomic wt. : 6.941
element : Cobalt
symbol : Co
atomic num : 27
atomic wt. : 58.933
element : Carbon
symbol : C
atomic num : 6
atomic wt. : 12.011
element : Oxygen
symbol : O
atomic num : 8
atomic wt. : 15.999
Li3Co4CO2 (atomic weight) : 300.565
Good luck, let me know if you need additional help fitting the pieces together.