silver-crow 发表于 2023-3-20 10:57:19

新手求助

题目:写一个程序,对用户输入的整数进行求和。实现以下要求:
               A. 用户可以输入整数和浮点数
               B. 用户可以在同一行输入多个数字,数字之间可以是任意一个分隔符
               C. 结果保留两位小数       

#include<stdio.h>
#include<math.h>

int main()
{
    //定义
    char num, NUM;
    /*judge用来判断输入数据的循环是否结束
    mid1用来实现数据类型的转化,字符-->浮点型
    mid2第一次使用用于判断用户输入数据中是否只含有非数值部分中计算character的值;第二次使用用于表示数组NUM及其长度
    mid3用于将数组NUM中存储的数据转化为浮点型
    mid4和mid5用于表示小数点前后的位数
    length表示num数组长度
    character用于判断用户输入数据中是否只含有非数值部分的最终判断
    judge2用于表示NUM中是否含有小数点(0表示无,1表示有)*/
    int judge1, judge2, mid1, mid2, mid3, mid4, mid5, length, character = 0;
    float sum, answer;

    //输入数据
    for(answer = 0, judge1 = 0, sum = 0;judge1 == 0;)
    {
      printf("请输入合法的数字:\n");
      printf("请不要连续输入两个<.>!\n");
      gets(num);

      //计算输入的数值的长度
      for(length = 0; length < 256 ;length++)
      {
            if(num == '\0')
            {
                break;
            }
      }
      printf("length = %d\n", length);

      //判断用户输入的数值字符串是否只含有非数值值,若是则character数值同length,即程序终止输入
      for(mid2 = 0; mid2 < length; mid2++)
      {
            if(num < '0' || num > '9')
            {
                character++;
            }
      }
      if(character == length)
      {
            judge1 = 1;
            break;
      }
      printf("judge1 = %d\n", judge1);

      mid2 = 0;

      //用sum将输入的数值字符串转换为对应大小的int型数值
      for(mid1 = 0; mid1 < length; mid1++)
      {
            if(num < '0' || num > '9' || num != '.')
            {
                //用于求mid4和mid5的
                for(mid3 = 0, mid4 = 0; NUM != '.' && mid3 < mid2; mid3++)
                {
                  if(NUM == '.')
                  {
                        judge2 = 1;
                  }
                  mid4++;
                }
                if(judge2 == 1)
                {
                  mid5 = mid2 - mid4 - 1;
                }
                else
                {
                  mid5 = mid2 - mid4;
                }
                //用于计算结果的
                //小数点前的部分
                for(mid3 = 0; mid4 >= 0; mid4--, mid3++)
                {
                  if(NUM == '.')
                  {
                        mid3++;
                        break;
                  }
                  sum =sum + (NUM - '0') * pow(10, (mid4 - 1));
                }
                for(mid4 = 1; mid4 <= mid5; mid4++, mid3++)
                {
                  sum = sum + (NUM - '0') * pow(10, (-mid4));
                }
                sum =sum + (num - '0') * pow(10,(length - mid - 1));
                continue;
            }
            else
            {
                NUM = num;
                mid2++;
            }
      }

      answer = answer + sum;
      sum = 0;
    }

    //输出结果
    printf("结果是%d", answer);

    return 0;
}

运行结果:请输入合法的数字:123
                length = 3

提问:为什么程序运行到第34行就结束了,不进入目标为“判断用户输入的数值字符串是否只含有非数值值,若是则character数值同length,即程序终止输入”的循环呢?

isdkz 发表于 2023-3-20 10:57:20

silver-crow 发表于 2023-3-20 13:53
修改成fgets之后输出的结果还是之前发的那个

抱歉刚刚的修改建议没有解决问题。根据你给出的代码,我发现其中还有一些问题。我对你的代码进行了修改,以满足题目要求。请参考以下代码:

#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <ctype.h>

float parse_and_sum(const char *input)
{
    float sum = 0;
    float number = 0;
    int decimal = 0;
    int decimal_multiplier = 1;

    for (int i = 0; i < strlen(input); i++)
    {
      char c = input;

      if (isdigit(c))
      {
            if (decimal)
            {
                number += (c - '0') / (10.0 * decimal_multiplier);
                decimal_multiplier *= 10;
            }
            else
            {
                number = number * 10 + (c - '0');
            }
      }
      else if (c == '.')
      {
            if (!decimal)
            {
                decimal = 1;
            }
      }
      else
      {
            sum += number;
            number = 0;
            decimal = 0;
            decimal_multiplier = 1;
      }
    }
    sum += number;

    return sum;
}

int main()
{
    char input;
    float sum = 0;

    while (1)
    {
      printf("请输入合法的数字(输入非数字字符以结束):\n");
      fgets(input, 256, stdin);

      float current_sum = parse_and_sum(input);

      if (current_sum == 0)
      {
            break;
      }

      sum += current_sum;
    }

    printf("结果是:%.2f\n", sum);

    return 0;
}

这个版本的程序首先定义了一个 parse_and_sum 函数,该函数接收一个字符串输入并计算其中数字的总和。在 main 函数中,程序使用 fgets 函数读取用户输入,并调用 parse_and_sum 函数计算当前输入的总和。如果当前输入的总和为零,则停止输入,否则将当前输入的总和添加到累积总和中。最后,打印累积总和,保留两位小数。

注意:这个程序版本仍然存在一些局限性,例如,没有处理输入中可能存在的负数。如果需要处理负数,可以进一步修改 parse_and_sum 函数。

isdkz 发表于 2023-3-20 11:01:12

程序在第34行没有结束,而是在第37行中断了。问题出在第37行的 gets() 函数。使用 gets() 函数来接收字符串输入是不安全的,因为它不检查缓冲区的大小,可能导致缓冲区溢出。建议使用 fgets() 函数替换 gets() 函数,这样可以指定缓冲区的大小,避免缓冲区溢出问题。

将第37行的 gets(num); 更改为 fgets(num, 256, stdin);。

此外,程序的逻辑还存在其他问题。例如,第76行的条件判断 if(num < '0' || num > '9' || num != '.') 应更改为 if(num >= '0' && num <= '9' || num == '.'),因为原来的条件判断逻辑不正确。

silver-crow 发表于 2023-3-20 13:53:47

isdkz 发表于 2023-3-20 11:01
程序在第34行没有结束,而是在第37行中断了。问题出在第37行的 gets() 函数。使用 gets() 函数来接收字符串 ...

修改成fgets之后输出的结果还是之前发的那个

jhq999 发表于 2023-3-20 15:20:48

本帖最后由 jhq999 于 2023-3-20 15:26 编辑

#include <stdio.h>
int main ()
{
    char s={0};
    scanf("%[^\n]",s);
    int i,j,isnum,n;
    double sum,num;
    for(i=0,j=i,sum=0,isnum=0;s;i+=1)
    {
      if((s>='0'&&'9'>=s)||'.'==s)
      {
            if(0==isnum)j=i;
            isnum=1;
      }
      else
      {
            s=32;
            if(isnum)
            {
                sscanf(s+j,"%lf",&num);
                printf("%lf ",num);
                sum+=num;
            }
            isnum=0;
      }
    }
    if(isnum)
    {
      sscanf(s+j,"%lf",&num);
      printf("%lf ",num);
      sum+=num;
    }
    printf("\n%.2lf",sum);
    return 0;
}
rr3k123.6hhrh/234kjhg6f7 g
3.000000 123.600000 234.000000 6.000000 7.000000
373.60
Process returned 0 (0x0)   execution time : 15.134 s
Press any key to continue.
页: [1]
查看完整版本: 新手求助