大一编程小白求教代码哪里错了

题目来源及自己的思路

输入
第1行,一个整数n(1≤n≤10)n,表示这份试卷上涉及到的元素种类数

“很巧,这份卷子的计算题不涉及由两个字母命名的元素,如Ag、He不会出现!”

第2到n+1行,每行一个大写字母C、一个浮点数M(1≤M≤299.2572),以空格分隔,表示元素C的相对原子质量为M
第n+2行,一个整数T(1≤T≤10),表示分子式的数量。

“很巧,这份试卷上的分子式不会出现括号,如(NH4)2CO3不会出现!并且一个元素的单次出现,个数不会多于9个,即为个位数,如C12H22O11不会出现。”

第n+3到n+2+T行,每行一个仅由大写字母与数字组成的字符串s(1≤|s|≤25,|s|代表字符串长度),表示一个分子式(保证元素相对原子质量已知)。除了个数为1时数字会被省去,该字符串将会是单个大写字母与单个数字的交替。(甲烷是CH4而非C1H4。)

输出
T行,每行形如M(s) = m,其中s为分子式,m为相对分子质量(保留6位有效数字并用科学计数法表示)。

科学计数法:用aEb表示a×10b,本题中b为有前导零的三位有符号整数(000前用+,很显然本题输出中不会用到-),如3.34701E+000、1.00000E+014。

相关代码

#include <ctype.h>
#include <stdio.h>
int main()
{
    int n, t, i, l;
    double m[100];
    char s[100];
    char ele[10] = { 0 };
    double wei;
    scanf("%d", &n);
    for (i = 0; i < n; i++) {
        scanf("%s%lf", &ele, &wei);
        m[ele[i] - 'A'] = wei;
    }
    scanf("%d", &t);
    double tot = 0;
    int exp = 0;
    for (l = 0; l < t; l++) {
        scanf("%s", s);
        for (i = 0; s[i]; i++) {
            if (isupper(s[i])) {
                if (isdigit(s[i + 1])) {
                    tot += (s[i + 1] - '0') * m[s[i] - 'A'];
                } else {
                    tot += m[s[i] - 'A'];
                }
            }
        }
        if (tot < 10) {
            printf("M(%s)=%.5lfE+000\n", s, tot);
        } else {
            while (tot >= 10) {
                tot /= 10;
                exp++;
            }
            printf("M(%s)=%.5lfE+%3d\n", s, exp);
        }
    }
    return 0;
}

你期待的结果是什么?实际看到的错误信息又是什么?

求教哪里错了

阅读 1.6k
1 个回答

所有修改的地方都加了注释

#include <ctype.h>
#include <stdio.h>
int main()
{
    int n, t, i, l;
    double m[100];
    char s[100];
    char ele[10] = { 0 };
    double wei;
    scanf("%d", &n);
    for (i = 0; i < n; i++) {
        scanf("%s%lf", &ele, &wei);
        // 单个元素的质量,元素字符总是在第一个位置。
        m[ele[0] - 'A'] = wei;
    }
    scanf("%d", &t);
    double tot = 0;
    int exp = 0;
    for (l = 0; l < t; l++) {
        scanf("%s", s);
        // 每个分子式前,清空质量之和。
        tot = 0;
        for (i = 0; s[i]; i++) {
            char c = s[i];
            // 1) 若为大写字母,加数量1
            // 2) 否则必为数字 n,加前元素数量 n-1
            if (isupper(c))
                tot += m[c - 'A'];
            else
                tot += m[s[i-1] - 'A'] * ((c - '0') - 1);
        }
        if (tot < 10) {
            printf("M(%s)=%.5lfE+000\n", s, tot);
        } else {
            while (tot >= 10) {
                tot /= 10;
                exp++;
            }
            // 这里有 3 个参数,且前置零应使用 "%03d"
            printf("M(%s)=%.5lfE+%03d\n", s, tot, exp);
        }
    }
    return 0;
}

运行一下

gcc a.c && echo "2\nA 1.2\nB 3.4\n2\nAB2\nA5B6" | ./a.out

结果是这样的

M(AB2)=8.00000E+000
M(A5B6)=2.64000E+001
撰写回答
你尚未登录,登录后可以
  • 和开发者交流问题的细节
  • 关注并接收问题和回答的更新提醒
  • 参与内容的编辑和改进,让解决方法与时俱进