c# 尝试通过用户输入返回总和或平均值

smdnsysy  于 2023-02-27  发布在  C#
关注(0)|答案(1)|浏览(201)

我已经写了下面的代码:

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

int main(void)
{
    int *hours_worked;
    int size;
    int suma = 0;

    printf("Enter the number of weeks you have taken CS50: ");
    scanf("%d", &size);

    hours_worked = (int*) malloc(size * sizeof(int));

    if(hours_worked == NULL)
    {
        printf("Memory Allocation failed!");
        return 1;
    }
    for (int i=0; i<size; i++)
    {
    printf("Week %i ", i);
    hours_worked[i] = get_int("HW Hours :\n");
    }

    //calculez suma

    for (int i = 0; i < size; i++)
    {
        suma = suma + hours_worked[i];
    }
    float average = suma / size;

    char *value = (char*) malloc(sizeof(char));
    if(value == NULL)
    {
        printf("Memory Allocation failed!");
        return 1;
    }
    *value = '\0';
    if (strcmp(value, "T") != 0 || strcmp(value, "A") != 0)
    {
        *value = get_char("Enter T For total hours, A for average hours per week: ");    
    }

    else if (strcmp(value, "T") == 0)
    {
        
        printf("Total hours worked: %i\n", suma);
    }
    else 
    {
        printf("This week you worked on average: %f", average);
        
    }
    free(value);
    free(hours_worked);
}

我试图得到一个总和或平均值的基础上用户输入。用户输入的周数,代码计算总和或平均周数,但未能分享结果。任何想法,你会如何做这一点不同?
我期待看到这个:

$ ./test
Number of weeks taking CS50: 3
Week 0 HW Hours: 3
Week 1 HW Hours: 7
Week 2 HW Hours: 10
Enter T for total hours, A for average hours per week: A
6.7 hours

$ ./test
Number of weeks taking CS50: 2
Week 0 HW Hours: 2
Week 1 HW Hours: 8
Enter T for total hours, A for average hours per week: T
10.0 hours
t9aqgxwy

t9aqgxwy1#

在C语言中,string被定义为一系列非零字节,后跟一个零值字节(空字符字节,'\0')。
字符串"T"由两个字节组成:'T''\0'
零字节相当于sentinel value,允许strstrstrcmp这样的函数知道字符串的长度,而不需要显式地提供该信息。
strcmp这样的函数传递一个非空终止序列会调用Undefined Behaviour,因为该函数不再知道何时停止读取字符,并且将继续读取相邻的内存位置,直到找到一个零字节,触发crashes your program的某个东西,或者使键盘着火。

char *value = (char*) malloc(sizeof(char));
if(value == NULL)
{
    printf("Memory Allocation failed!");
    return 1;
}
*value = '\0';
if (strcmp(value, "T") != 0 || strcmp(value, "A") != 0)
{
*value = get_char("Enter T For total hours, A for average hours per week: ");    
}
else if (strcmp(value, "T") == 0)
/* ... */

value只能包含空字符串,只有空字节的空间。
在用另一个字符覆盖空字节之前,只将一个空字符串与字符串"T""A"进行比较,这样就可以避免未定义的行为,此时,如果用户提供了空字节以外的任何内容,value就不再是字符串。
幸运的是,else if条件下的比较永远不会发生。
读取单个字符并将其直接与'T''A'进行比较会更容易,而完全避免使用strcmp
或者,使用get_string,但要注意它可能返回值NULL,而该值不应传递给strcmp
否则,下面是手动构建已知长度的字符串的一个相当笨拙的示例:

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

int main(void)
{
    int length = 0;

    while (length < 1)
        length = get_int("Enter string length: ");

    char *str = malloc(1 + length);

    if (!str) {
        perror("malloc");
        return EXIT_FAILURE;
    }

    for (size_t i = 0; i < length; i++)
        str[i] = get_char("Enter character: ");

    str[length] = '\0';

    if (0 == strcmp(str, "hello"))
        puts("hi");
    else
        puts(str);

    free(str);
}

注意,在float average = suma / size;中,sumasize都是整数,所以这将执行 * 整数除法 *,truncating是结果。
只有在除法运算之后,值才会转换为浮点数。您应该先使用强制转换(suma / (float) size)显式转换其中一个操作数。另一个操作数将隐式转换。
除非您想重新调用输入的值,否则不需要分配额外的内存,因为您可以随时执行求和。
下面是一个需要存储输入以便稍后显示的示例。
一个二个一个一个

相关问题