我已经写了下面的代码:
# 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
1条答案
按热度按时间t9aqgxwy1#
在C语言中,string被定义为一系列非零字节,后跟一个零值字节(空字符字节,
'\0'
)。字符串
"T"
由两个字节组成:'T'
和'\0'
。零字节相当于sentinel value,允许
strstr
和strcmp
这样的函数知道字符串的长度,而不需要显式地提供该信息。向
strcmp
这样的函数传递一个非空终止序列会调用Undefined Behaviour,因为该函数不再知道何时停止读取字符,并且将继续读取相邻的内存位置,直到找到一个零字节,触发crashes your program的某个东西,或者使键盘着火。在
value
只能包含空字符串,只有空字节的空间。在用另一个字符覆盖空字节之前,只将一个空字符串与字符串
"T"
和"A"
进行比较,这样就可以避免未定义的行为,此时,如果用户提供了空字节以外的任何内容,value
就不再是字符串。幸运的是,
else if
条件下的比较永远不会发生。读取单个字符并将其直接与
'T'
或'A'
进行比较会更容易,而完全避免使用strcmp
。或者,使用
get_string
,但要注意它可能返回值NULL
,而该值不应传递给strcmp
。否则,下面是手动构建已知长度的字符串的一个相当笨拙的示例:
注意,在
float average = suma / size;
中,suma
和size
都是整数,所以这将执行 * 整数除法 *,truncating是结果。只有在除法运算之后,值才会转换为浮点数。您应该先使用强制转换(
suma / (float) size
)显式转换其中一个操作数。另一个操作数将隐式转换。除非您想重新调用输入的值,否则不需要分配额外的内存,因为您可以随时执行求和。
下面是一个需要存储输入以便稍后显示的示例。
一个二个一个一个