鱼C论坛

 找回密码
 立即注册
查看: 1470|回复: 4

[已解决]新手求助

[复制链接]
发表于 2023-3-20 10:57:19 | 显示全部楼层 |阅读模式
20鱼币
题目:写一个程序,对用户输入的整数进行求和。实现以下要求:
                 A. 用户可以输入整数和浮点数
                 B. 用户可以在同一行输入多个数字,数字之间可以是任意一个分隔符
                 C. 结果保留两位小数       

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

int main()
{
    //定义
    char num[256], NUM[256];
    /*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[length] == '\0')
            {
                break;
            }
        }
        printf("length = %d\n", length);

        //判断用户输入的数值字符串是否只含有非数值值,若是则character数值同length,即程序终止输入
        for(mid2 = 0; mid2 < length; mid2++)
        {
            if(num[mid2] < '0' || num[mid2] > '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[mid1] < '0' || num[mid1] > '9' || num[mid1] != '.')
            {
                //用于求mid4和mid5的
                for(mid3 = 0, mid4 = 0; NUM[mid3] != '.' && mid3 < mid2; mid3++)
                {
                    if(NUM[mid3] == '.')
                    {
                        judge2 = 1;
                    }
                    mid4++;
                }
                if(judge2 == 1)
                {
                    mid5 = mid2 - mid4 - 1;
                }
                else
                {
                    mid5 = mid2 - mid4;
                }
                //用于计算结果的
                //小数点前的部分
                for(mid3 = 0; mid4 >= 0; mid4--, mid3++)
                {
                    if(NUM[mid3] == '.')
                    {
                        mid3++;
                        break;
                    }
                    sum =sum + (NUM[mid3] - '0') * pow(10, (mid4 - 1));
                }
                for(mid4 = 1; mid4 <= mid5; mid4++, mid3++)
                {
                    sum = sum + (NUM[mid3] - '0') * pow(10, (-mid4));
                }
                sum =sum + (num[mid] - '0') * pow(10,(length - mid - 1));
                continue;
            }
            else
            {
                NUM[mid2] = num[mid1];
                mid2++;
            }
        }

        answer = answer + sum;
        sum = 0;
    }

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

    return 0;
}

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

提问:为什么程序运行到第34行就结束了,不进入目标为“判断用户输入的数值字符串是否只含有非数值值,若是则character数值同length,即程序终止输入”的循环呢?
最佳答案
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[i];

        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[256];
    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 函数。

最佳答案

查看完整内容

抱歉刚刚的修改建议没有解决问题。根据你给出的代码,我发现其中还有一些问题。我对你的代码进行了修改,以满足题目要求。请参考以下代码: 这个版本的程序首先定义了一个 parse_and_sum 函数,该函数接收一个字符串输入并计算其中数字的总和。在 main 函数中,程序使用 fgets 函数读取用户输入,并调用 parse_and_sum 函数计算当前输入的总和。如果当前输入的总和为零,则停止输入,否则将当前输入的总和添加到累积总和 ...
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复

使用道具 举报

发表于 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[i];

        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[256];
    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 函数。
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复

使用道具 举报

发表于 2023-3-20 11:01:12 | 显示全部楼层
程序在第34行没有结束,而是在第37行中断了。问题出在第37行的 gets() 函数。使用 gets() 函数来接收字符串输入是不安全的,因为它不检查缓冲区的大小,可能导致缓冲区溢出。建议使用 fgets() 函数替换 gets() 函数,这样可以指定缓冲区的大小,避免缓冲区溢出问题。

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

此外,程序的逻辑还存在其他问题。例如,第76行的条件判断 if(num[mid1] < '0' || num[mid1] > '9' || num[mid1] != '.') 应更改为 if(num[mid1] >= '0' && num[mid1] <= '9' || num[mid1] == '.'),因为原来的条件判断逻辑不正确。
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复

使用道具 举报

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

修改成fgets之后输出的结果还是之前发的那个
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复

使用道具 举报

发表于 2023-3-20 15:20:48 | 显示全部楼层
本帖最后由 jhq999 于 2023-3-20 15:26 编辑
#include <stdio.h>
int main ()
{
    char s[1000]={0};
    scanf("%[^\n]",s);
    int i,j,isnum,n;
    double sum,num;
    for(i=0,j=i,sum=0,isnum=0;s[i];i+=1)
    {
        if((s[i]>='0'&&'9'>=s[i])||'.'==s[i])
        {
            if(0==isnum)j=i;
            isnum=1;
        }
        else
        {
            s[i]=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.
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复

使用道具 举报

您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

小黑屋|手机版|Archiver|鱼C工作室 ( 粤ICP备18085999号-1 | 粤公网安备 44051102000585号)

GMT+8, 2024-12-25 20:57

Powered by Discuz! X3.4

© 2001-2023 Discuz! Team.

快速回复 返回顶部 返回列表