-1

I need to do a proyect that calculates me the molar mass of any molecule entered by the user. For example if the user types CO2, my program needs to identify C (that is associated with a matrix with its mass), then identify O (associated with its mass) and multiply it by two, and add them up.

I was thinking of using strings of character for the each element.

Im very new in programing and I have learned just the basics pretty much.

how would you guys recommend me to do it? Im pretty lost

Thank you very much

Raphaelle
  • 1
  • 2
  • 2
    1. A table of proper atom names along with their mass - a `struct`. 2. Scan for Uppercase, followed optionally by multiple lowercases. 3. Scan digits. 4. Multiply and add. 5. Rinse and repeat until end of string. 6. Profit. – Jongware Nov 09 '15 at 23:59

2 Answers2

1

It seems like the big challenge here is parsing the text, so you can pass full elements to a function to do your counting. You'll need a string to take the input, but I would strongly caution you away from the std string for this.

Instead, try an array of char.

Some things to consider:

  • How big does the array need to be?

  • What kind of characters will I accept? (spaces?)

  • How do I know when the user is done with input? (something something null-terminated...)

  • How will I move through the array?

  • What defines an element? (If it's capital letters, take a look at ASCII values for comparing them)

  • What do I do with an element when I find it?

You asked for a starting place, so I'm reluctant to give out any specific code. Take a look at Jongware's comment for a good outline of what your program needs to do. Tackle it a piece at a time (answer the questions in this post and you'll be fine with input) and check it off your outline when you're done. Good luck!

Robotski
  • 38
  • 1
  • 7
C-Kennelly
  • 58
  • 6
1

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.

David C. Rankin
  • 81,885
  • 6
  • 58
  • 85