みなさまありがとうございました.無事解決しました.
C
1#include <stdio.h>
2#include <stdlib.h>
3#include <string.h>
4
5
6typedef struct Material {
7 int type; //0=Atom, 1=Molecule
8} Material_t;
9
10typedef struct Atom {
11 int material_type; //0=Atom, 1=Molecule
12 char name[4];
13 double weight;
14} Atom_t;
15
16Atom_t atoms[] = {
17 { 0, "H" , 1.00798 },
18 { 0, "He", 4.0026 },
19 { 0, "Li", 6.968 },
20 { 0, "Be", 9.01218 },
21 { 0, "B" , 10.814 },
22 { 0, "C" , 12.0106 },
23 { 0, "N" , 14.0069 },
24 { 0, "O" , 15.9994 },
25 { 0, "F" , 18.9984 },
26 { 0, "Ne", 20.1797 },
27 { 0, "Na", 22.9898 },
28 { 0, "Mg", 24.306 },
29 { 0, "Al", 26.9815 },
30 { 0, "Si", 28.085 },
31 { 0, "P" , 30.9738 },
32 { 0, "S" , 32.068 },
33 { 0, "Cl", 35.452 },
34 { 0, "Ar", 39.948 },
35 { 0, "K" , 39.0983 },
36 { 0, "Ca", 40.078 },
37 { 0, "Sc", 44.9559 },
38 { 0, "Ti", 47.867 },
39 { 0, "V" , 50.9415 },
40 { 0, "Cr", 51.9961 },
41 { 0, "Mn", 54.938 },
42 { 0, "Fe", 55.845 },
43 { 0, "Co", 58.9332 },
44 { 0, "Ni", 58.6934 },
45 { 0, "Cu", 63.546 },
46 { 0, "Zn", 65.38 },
47 { 0, "Ga", 69.723 },
48 { 0, "Ge", 72.630 },
49 { 0, "As", 74.9216 },
50 { 0, "Se", 78.971 },
51 { 0, "Br", 79.904 },
52 { 0, "Kr", 83.798 },
53 { 0, "Rb", 85.4678 },
54 { 0, "Sr", 87.62 },
55 { 0, "Y" , 88.9058 },
56 { 0, "Zr", 91.224 },
57 { 0, "Nb", 92.9064 },
58 { 0, "Mo", 95.95 },
59 { 0, "Tc", 99 },
60 { 0, "Ru", 101.07 },
61 { 0, "Rh", 102.906 },
62 { 0, "Pd", 106.42 },
63 { 0, "Ag", 107.868 },
64 { 0, "Cd", 112.414 },
65 { 0, "In", 114.818 },
66 { 0, "Sn", 118.710 },
67 { 0, "Sb", 121.760 },
68 { 0, "Te", 127.60 },
69 { 0, "I" , 126.904 },
70 { 0, "Xe", 131.293 },
71 { 0, "Cs", 132.905 },
72 { 0, "Ba", 137.327 },
73 { 0, "La", 138.905 },
74 { 0, "Ce", 140.116 },
75 { 0, "Pr", 140.908 },
76 { 0, "Nd", 144.242 },
77 { 0, "Pm", 145 },
78 { 0, "Sm", 150.36 },
79 { 0, "Eu", 151.964 },
80 { 0, "Gd", 157.25 },
81 { 0, "Tb", 158.925 },
82 { 0, "Dy", 162.500 },
83 { 0, "Ho", 164.930 },
84 { 0, "Er", 167.259 },
85 { 0, "Tm", 168.934 },
86 { 0, "Yb", 173.045 },
87 { 0, "Lu", 174.967 },
88 { 0, "Hf", 178.49 },
89 { 0, "Ta", 180.948 },
90 { 0, "W" , 183.84 },
91 { 0, "Re", 186.207 },
92 { 0, "Os", 190.23 },
93 { 0, "Ir", 192.217 },
94 { 0, "Pt", 195.084 },
95 { 0, "Au", 196.967 },
96 { 0, "Hg", 200.592 },
97 { 0, "Tl", 204.384 },
98 { 0, "Pb", 207.2 },
99 { 0, "Bi", 208.980 },
100 { 0, "Po", 210 },
101 { 0, "At", 210 },
102 { 0, "Rn", 222 },
103 { 0, "Fr", 223 },
104 { 0, "Ra", 226 },
105 { 0, "Ac", 227 },
106 { 0, "Th", 232.038 },
107 { 0, "Pa", 231.036 },
108 { 0, "U" , 238.029 },
109 { 0, "Np", 237 },
110 { 0, "Pu", 239 },
111 { 0, "Am", 243 },
112 { 0, "Cm", 247 },
113 { 0, "Bk", 247 },
114 { 0, "Cf", 252 },
115 { 0, "Es", 252 },
116 { 0, "Fm", 257 },
117 { 0, "Md", 258 },
118 { 0, "No", 259 },
119 { 0, "Lr", 262 },
120 { 0, "Rf", 267 },
121 { 0, "Db", 268 },
122 { 0, "Sg", 271 },
123 { 0, "Bh", 272 },
124 { 0, "Hs", 277 },
125 { 0, "Mt", 276 },
126 { 0, "Ds", 281 },
127 { 0, "Rg", 280 },
128 { 0, "Cn", 285 },
129 { 0, "Nh", 278 },
130 { 0, "Fl", 289 },
131 { 0, "Mc", 289 },
132 { 0, "Lv", 293 },
133 { 0, "Ts", 293 },
134 { 0, "Og", 294 },
135 {-1, "", -1 } //EOD
136};
137
138Atom_t *search_atom(char *name) {
139 Atom_t *p;
140 for (p=atoms; p->weight>0; p++) {
141 if (strcmp(p->name, name) == 0) return p;
142 }
143
144 exit(0);
145 return NULL; //Not exist
146}
147
148typedef struct MaterialValue {
149 Material_t *material; //Atom or Molecule
150 double ratio;
151} MaterialValue_t;
152
153typedef struct Molecule {
154 int material_type; //0=Atom, 1=Molecule
155 int materials_count;
156 MaterialValue_t materials[64];
157} Molecule_t;
158
159Molecule_t *newMolecule() {
160 Molecule_t *molecule = (Molecule_t *)malloc(sizeof(Molecule_t));
161 molecule->material_type = 1;
162 molecule->materials_count = 0;
163 return molecule;
164}
165
166void add(Molecule_t *molecule, Material_t *material) {
167 MaterialValue_t *mv = &(molecule->materials[molecule->materials_count++]);
168 mv->material = material;
169 mv->ratio = 1.0;
170}
171
172void setRatio(Molecule_t *molecule, double ratio) {
173 molecule->materials[molecule->materials_count-1].ratio = ratio;
174}
175
176double getWeight(Molecule_t *molecule) {
177 int i;
178 double weight = 0;
179 for(i=0; i<molecule->materials_count; i++) {
180 MaterialValue_t *mv = &molecule->materials[i];
181 if(mv->material->type == 0) { //Atom
182 weight += ((Atom_t *)(mv->material))->weight * mv->ratio;
183 } else { //Molecule
184 weight += getWeight((Molecule_t *)(mv->material)) * mv->ratio;
185 }
186 }
187 return weight;
188}
189
190//Stack
191Molecule_t *stack[64];
192int stack_pointer = 0;
193void stack_push(Molecule_t *molecule) {
194 stack[stack_pointer++] = molecule;
195}
196Molecule_t *stack_pop() {
197 return stack[--stack_pointer];
198}
199Molecule_t *stack_peek() {
200 return stack[stack_pointer-1];
201}
202
203//Analysis
204int isDigit(char c) {
205 return ('0' <= c && c <= '9');
206}
207int isDigitOrPeriod(char c) {
208 return (isDigit(c) || c == '.');
209}
210void JudgeBrackets(char samplename[64]) {
211
212 char *bra, *ket;
213 int start, end;
214
215 bra = strchr(samplename, '(');
216 ket = strchr(samplename, ')');
217
218 if ((bra == NULL) && (ket == NULL)) {
219 // Not exist brackets
220 return;
221 } else if ((bra == NULL) && (ket != NULL)) {
222 puts("Not exist '('");
223 exit(0);
224 } else if ((bra != NULL) && (ket == NULL)) {
225 puts("Not exist ')'");
226 exit(0);
227 } else {
228 // Exist brackets
229 start = (int)(bra - samplename);
230 end = (int)(ket - samplename);
231 if ((end - start) == 1) {
232 puts("Error");
233 puts("Nothing is entered in parenthese.");
234 exit(0);
235 }
236 return;
237 }
238}
239
240
241Molecule_t *parse(void) {
242 int i, j, k;
243 char v[64] = {}, samplename[64] = {};
244
245 puts("Enter sample name.");
246 printf("Chemical formula: ");
247 scanf("%s", samplename);
248
249 JudgeBrackets(samplename);
250
251 stack_push(newMolecule());
252 for (i=0; i<strlen(samplename); i++) {
253 memset(v, 0, sizeof(v));
254 v[0] = samplename[i];
255 if (isDigit(v[0])) {
256 for (j=i+1, k=1; j<strlen(samplename) && isDigitOrPeriod(samplename[j]); k++, j++, i++) {
257 v[k] = samplename[j];
258 }
259 setRatio(stack_peek(), atof(v));
260 } else if (strcmp(v, "(") == 0) {
261 stack_push(newMolecule());
262 } else if (strcmp(v, ")") == 0) {
263 Material_t *material = (Material_t *)stack_pop();
264 add(stack_peek(), material);
265 } else {
266
267 if ((samplename[i+1]>='a') && (samplename[i+1]<='z')) {
268 v[1] = samplename[i+1];
269 i++;
270 }
271
272 add(stack_peek(), (Material_t *)search_atom(v));
273 }
274 }
275 return stack_pop();
276}
277
278int main(int argc, char *argv[]) {
279
280 double MW; //Molecular Weight
281
282 MW = getWeight(parse());
283 printf("%lf g/mol\n", MW);
284
285 return 0;
286}
287