英文:
Trying to return either a sum or average by user input
问题
Here's the translated code:
# include <stdio.h>
# include <stdlib.h>
#include <string.h>
#include <cs50.h>
int main(void)
{
int *hours_worked;
int size;
int suma = 0;
printf("输入您已经学习CS50的周数:");
scanf("%d", &size);
hours_worked = (int*) malloc(size * sizeof(int));
if(hours_worked == NULL)
{
printf("内存分配失败!");
return 1;
}
for (int i=0; i<size; i++)
{
printf("第 %i 周", i);
hours_worked[i] = get_int("每周学习小时数:\n");
}
// 计算总和
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("内存分配失败!");
return 1;
}
*value = '# include <stdio.h>
# include <stdlib.h>
#include <string.h>
#include <cs50.h>
int main(void)
{
int *hours_worked;
int size;
int suma = 0;
printf("输入您已经学习CS50的周数:");
scanf("%d", &size);
hours_worked = (int*) malloc(size * sizeof(int));
if(hours_worked == NULL)
{
printf("内存分配失败!");
return 1;
}
for (int i=0; i<size; i++)
{
printf("第 %i 周", i);
hours_worked[i] = get_int("每周学习小时数:\n");
}
// 计算总和
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("内存分配失败!");
return 1;
}
*value = '\0';
if (strcmp(value, "T") != 0 || strcmp(value, "A") != 0)
{
*value = get_char("输入T获取总小时数,输入A获取每周平均小时数:");
}
else if (strcmp(value, "T") == 0)
{
printf("总学习小时数:%i\n", suma);
}
else
{
printf("本周您的平均学习小时数:%f", average);
}
free(value);
free(hours_worked);
}
';
if (strcmp(value, "T") != 0 || strcmp(value, "A") != 0)
{
*value = get_char("输入T获取总小时数,输入A获取每周平均小时数:");
}
else if (strcmp(value, "T") == 0)
{
printf("总学习小时数:%i\n", suma);
}
else
{
printf("本周您的平均学习小时数:%f", average);
}
free(value);
free(hours_worked);
}
This code appears to be designed to calculate either the total hours or the average hours based on user input. It prompts the user for the number of weeks and then collects the hours worked for each week. Finally, it calculates and displays either the total hours or the average hours per week based on the user's choice.
英文:
Hey I have written the below code:
# 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 = '# 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);
}
';
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);
}
I am trying to get either a sum or average based on user input. User enters numbers of weeks, the code calculates sum of either weeks or average, but fails to share the result.
Any ideas how you would do this different?
I was expecting to see this:
$ ./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
or
$ ./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
得分: 0
在C语言中,字符串被定义为一系列非零字节后跟一个零值字节(空字符字节,'\0'
)。
字符串"T"
由两个字节组成:'T'
和'\0'
。
零字节充当哨兵值,允许函数如strstr
和strcmp
知道字符串的长度,而无需显式提供该信息。
将非空终止的序列传递给strcmp
之类的函数会引发未定义行为,因为函数不再知道何时停止读取字符,它将继续读取相邻的内存位置,直到找到零字节、触发某些东西导致程序崩溃,或者点燃您的键盘。
在
char *value = (char*) malloc(sizeof(char));
if(value == NULL)
{
printf("Memory Allocation failed!");
return 1;
}
*value = '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)
/* ... */
';
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] = '#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);
}
';
if (0 == strcmp(str, "hello"))
puts("hi");
else
puts(str);
free(str);
}
请注意,在float average = suma / size;
中,suma
和size
都是整数,因此这将执行整数除法,截断结果。
只有在除法之后才将值转换为浮点数。您应该在之前使用强制转换(suma / (float) size
)显式转换操作数之一。另一个操作数将被隐式转换。
除非您想要记住输入的值,否则无需分配额外的内存,因为您可以在进行计算时逐步执行求和。
这是一个示例,需要存储输入以便以后显示:
#include <cs50.h>
#include <stdio.h>
#include <stdlib.h>
int main(void)
{
int weeks = get_int("Enter the number of weeks you have taken CS50: ");
if (weeks < 1) {
puts("You should get started!");
return EXIT_SUCCESS;
}
int *hours = malloc(sizeof *hours * weeks);
if (!hours) {
perror("malloc");
return EXIT_FAILURE;
}
int total = 0;
for (int i = 0; i < weeks; i++) {
hours[i] = get_int("Week %d HW hours: ", i);
total += hours[i];
}
float average = total / (float) weeks;
char selection = get_char("Enter T For total hours, A for average hours per week, W for weekly hours: ");
if ('T' == selection)
printf("Total hours: %d\n", total);
else if ('A' == selection)
printf("Average hours: %.2f\n", average);
else if ('W' == selection)
for (int i = 0; i < weeks; i++)
printf("Week %d HW hours = %d\n", i, hours[i]);
free(hours);
}
nter the number of weeks you have taken CS50: 5
Week 0 HW hours: 4
Week 1 HW hours: 2
Week 2 HW hours: 5
Week 3 HW hours: 4
Week 4 HW hours: 6
Enter T For total hours, A for average hours per week, W for weekly hours: W
Week 0 HW hours = 4
Week 1 HW hours = 2
Week 2 HW hours = 5
Week 3 HW hours = 4
Week 4 HW hours = 6
英文:
In C, a string is defined as a sequence of nonzero bytes followed by a zero value byte (the null character byte, '\0'
).
The string "T"
consists of two bytes: 'T'
and '\0'
.
The zero byte works as a sentinel value, allowing functions like strstr
and strcmp
to know how long a string is without you needing to provide that information explicitly.
Passing a non-null terminated sequence to a function like strcmp
invokes Undefined Behaviour, as the function no longer knows when to stop reading characters, and will carry on reading adjacent memory locations until it finds a zero byte, trips something that crashes your program, or lights your keyboard on fire.
In
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
can only contain the empty string, having room for only the null byte.
You manage to avoid undefined behaviour by only comparing an empty string against the strings "T"
and "A"
, before overwriting the null byte with another character, at which point value
is no longer a string if the user provides anything other than the null byte.
The comparison in the else if
condition can never occur, luckily.
It would be easier to read a single character and compare it directly against 'T'
or 'A'
, avoiding strcmp
all together.
Alternatively, use get_string
, but watch out that it can return the value NULL
, which should not be passed to strcmp
.
Otherwise, here is a rather clunky example of manually building a string of a known length:
#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);
}
Note that in float average = suma / size;
, both suma
and size
are integers, so this will perform integer division, truncating the result.
Only after the division is the value converted to a float. You should explicitly convert one of the operands beforehand with a cast (suma / (float) size
). The other operand will be converted implicitly.
Unless you want to recall the values entered, there is no need to allocate additional memory, as you can perform your sums as you go.
Here is an example that requires storing the inputs in order to display them later.
#include <cs50.h>
#include <stdio.h>
#include <stdlib.h>
int main(void)
{
int weeks = get_int("Enter the number of weeks you have taken CS50: ");
if (weeks < 1) {
puts("You should get started!");
return EXIT_SUCCESS;
}
int *hours = malloc(sizeof *hours * weeks);
if (!hours) {
perror("malloc");
return EXIT_FAILURE;
}
int total = 0;
for (int i = 0; i < weeks; i++) {
hours[i] = get_int("Week %d HW hours: ", i);
total += hours[i];
}
float average = total / (float) weeks;
char selection = get_char("Enter T For total hours, A for average hours per week, W for weekly hours: ");
if ('T' == selection)
printf("Total hours: %d\n", total);
else if ('A' == selection)
printf("Average hours: %.2f\n", average);
else if ('W' == selection)
for (int i = 0; i < weeks; i++)
printf("Week %d HW hours = %d\n", i, hours[i]);
free(hours);
}
nter the number of weeks you have taken CS50: 5
Week 0 HW hours: 4
Week 1 HW hours: 2
Week 2 HW hours: 5
Week 3 HW hours: 4
Week 4 HW hours: 6
Enter T For total hours, A for average hours per week, W for weekly hours: W
Week 0 HW hours = 4
Week 1 HW hours = 2
Week 2 HW hours = 5
Week 3 HW hours = 4
Week 4 HW hours = 6
通过集体智慧和协作来改善编程学习和解决问题的方式。致力于成为全球开发者共同参与的知识库,让每个人都能够通过互相帮助和分享经验来进步。
评论