我用c 编写”输入分子式求分子量的程序“时,我的思路是这样的:
在一个函数中输入每个原子符号,返回它的原子量。主程序是查找输入的字符串,遇到大写字母,则将前面的字符取出,在函数中查找它,返回它的值,用数组下标记录字符在字符串中的位置,但不知为什么调用是总是出错;
问:
(1)如何解决这个问题?
(2)对于遇到有“()”的分子式怎么解决,如:Ca(OH)2
(3) 能为我提供一个更好的思路吗?
在一个函数中输入每个原子符号,返回它的原子量。主程序是查找输入的字符串,遇到大写字母,则将前面的字符取出,在函数中查找它,返回它的值,用数组下标记录字符在字符串中的位置,但不知为什么调用是总是出错;
问:
(1)如何解决这个问题?
(2)对于遇到有“()”的分子式怎么解决,如:Ca(OH)2
(3) 能为我提供一个更好的思路吗?
λ→β∣βλ
β→δ∣δn
δ→ξ∣ξθ∣(λ)
其中:λ是一个分子式;δ或是一个元素,或是一个带括号的(子)分子式,元素或是一个大写字母(记为ξ),或是一个大写字母和一个小写字母(记为ξθ);β或是一个δ,或是在δ之后接上一个整数n,δn表示β有n个δ的元素或(子)分子式。一个完整的分子式由若干个β组成。
当然一个正确的分子式除符合上述文法规则外,还应满足分子式本身的定义要求。
下面的程序输入分子式,按上述文法分析分子式,并计算出该分子式的分子量。例如:元素H的原子量是1,元素O的原子量是16。输入分子式H2O,程序计算出它的分子量为18(1*2+16)。程序中各元素的名及它的原子量从文件atom.dat中读入。#include <stdio.h>
#include <string.h>
#define MAXN 300
#define CMLEN 30
struct elem {
char name[3]; /*元素名*/
double v; /*原子量*/
}nTbl[MAXN];
char cmStr[CMLEN],*pos;
int c; FILE *fp;
double factor();
double atom() /*处理文法符号δ*/
{
char w[3];
int i; double num;
while((c=*pos++)==''||c=='\t'); /*略过空白字符*/
if(c=='\n') return 0.0;
if(c>='A'&&c<='Z'){ /*将元素名存入W*/
w[i=0]=c; c=*pos++;
if(c>='a'&&c<='z') w[++i]=c;
else pos--;
w[++i]='\0';
for(i=0;nTbl[i].v>0.0;i++)
if(strcmp(w,nTbl[i].name)==0)
return nTbl[i].v;
printf("\n元素表中没有所输入的元素:\t%s%n",w);
return -1.0;
}
else if(c=='(') {
if((num = factor() )<0.0) return -1.0; /*包括可能为空的情况*/
if(*pos++!=')')
{
printf("分子式中括号不匹配!\n");
return -1.0;
}
return num;
}
printf("分子式有非法字符\t%c\n",c);
return -1;
}double mAtom() /*处理文法符号β*/
{
double num; int n=1;
if(( num = atom())<0.0) return -1.0;
c=*pos++;
if(c>='0'&&c<='9'){
n=0;
while(c>='0'&&c<='9')
{
n = n*10+c-'10';
c=*pos++;
}
}
pos--;
return num*n;
}double factor() /*处理文法符号λ*/
{
double num=0.0,d;
if((num=mAtom())< 0.0) return -1.0;
while(*pos>='A'&&*pos<='Z'||*pos=='('){
if((d = mAtom())<0.0) return -1.0;
num += d;
}
return num;
}void main()
{
char fname[]="atom.dat"; /*元素名及其原子量文件*/
int i; double num;
if((fp=fopen(fname,"r"))==NULL){ /*以读方式打开正文文件*/
printf("Can not open %s file. \n",fname);
return;
}
i=0;
while(i<MAXN&&fscanf(fp,"%s%1f",nTbl[i].name,&nTbl[i].v)==2)
i++;
fclose(fp);
nTbl[i].v=-1.0;
while(1){ /*输入分子式和计算分子量循环,直至输入空行结束*/
printf("\n输入分子式!(空行结束)\n");
gets(cmStr);
pos=cmStr;
if(cmStr[0]=='\0') break;
if((num = factor())>0.0)
if(*pos!='\0') printf("分子式不完整!\n");
else printf("分子式的分子量为%f\n",num);
}
}