从数组和单独的结构计算平均值

时间:2018-08-04 03:21:29

标签: c

试图制作一个程序来打印输入到文件中的数据。

除了输入的标记的“计算平均值”之外,所有内容都可以正常工作。

即使看起来很简单,我也无法弄清楚该怎么做。

我当前遇到的错误是:

"temp->mark = temp->mark + studentArray[j];" (Invlalid operands to 
 binary + (have 'float' and 'char *').

非常感谢有人能帮助我。我尝试了以下

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

struct student{
    char name[30];
    int id;
    float mark;
};

int count = 0;
void student_update(char *stuadd);
void display(char *stuadd);

void main(int argc, char *studentArray[100])
{
    int choice;
    while(1)
    {
        printf("Welcome to Student Archives\n\n");
        printf("1. Display Students' Details\n");
        printf("2. Calculate average of all students’ marks \n");
        printf("3. Add new student to the record \n");
        printf("4. Quit Program\n");
        scanf("%d",&choice);

        switch(choice)
        {
        case 1:display(studentArray[100]);
            break;
        case 2:
            break;
        case 3:
            student_update(studentArray[100]);
            break;
        case 4: printf("Program Terminated.\n"); 
            exit(0);
        default: printf("Wrong Choice. Enter again\n");
            break;
        }
    }
}

void display(char *stuadd)
{
    FILE *fptr;
    char ch;
    int rec = count;
    fptr = fopen("stuadd.txt", "r");
    struct student *temp = (struct student *)malloc(sizeof(struct student));
    if (fptr == NULL)
        printf("File does not exist.");
    else
    {
        while (rec)
        {            
            fread(temp->name, 50, 1, fptr);
            printf(" %s\n", temp->name);
            fread(&temp->id, sizeof(int), 1, fptr);
            printf("%d", temp->id);
            fread(&temp->mark, sizeof(int), 1, fptr);
            printf("%.2f", temp->mark);

            rec--;
        }
    }
    fclose(fptr);
    free(temp);
    free(temp->name);
}

void calculateAverage(char *studentArray[100])
{
    struct student *temp = (struct student *)malloc(sizeof(struct student));
    int j;
    float avg;

    temp->mark  = avg = 0;

    for(j = 0; j < 100; j++)
    {
        temp->mark = temp->mark + studentArray[j];
    }

    avg = (float)temp->mark / j;

    printf("Average of students' total marks are: %.2f",avg);
}

void student_update(char *stuadd)
{
    FILE *fptr;
    fptr = fopen("stuadd.txt", "a+");
    struct student *temp = (struct student *)malloc(sizeof(struct student));

    if (fptr == NULL)
        printf("\nError.");
    else
    {
        printf("\nEnter the students' name\n");
        scanf(" %[^\n]s", temp->name);

        printf("Enter the students' ID\n");
        scanf("%d", &temp->id);

        printf("Enter the students' mark\n");
        scanf("%f", &temp->mark);

        fprintf(fptr, "%s %d %.2f", temp->name, temp->id, temp->mark);

        count++;
    }

    fclose(fptr);
    free(temp);
    free(temp->name);
}

1 个答案:

答案 0 :(得分:3)

发布的代码无法编译!

在ubuntu linux下,使用:

gcc -ggdb -Wall -Wextra -Wconversion -pedantic -std=gnu11 -c "untitled.c" (in directory: /home/richard/Documents/forum)

编译器输出以下内容:

untitled.c:16:6: warning: return type of ‘main’ is not ‘int’ [-Wmain]
 void main(int argc, char *studentArray[100])
      ^~~~

untitled.c: In function ‘main’:
untitled.c:16:15: warning: unused parameter ‘argc’ [-Wunused-parameter]
 void main(int argc, char *studentArray[100])
               ^~~~

untitled.c: In function ‘display’:
untitled.c:48:10: warning: unused variable ‘ch’ [-Wunused-variable]
     char ch;
          ^~

untitled.c:45:20: warning: unused parameter ‘stuadd’ [-Wunused-parameter]
 void display(char *stuadd)
                    ^~~~~~

untitled.c: In function ‘calculateAverage’:
untitled.c:83:33: error: invalid operands to binary + (have ‘float’ and ‘char *’)
         temp->mark = temp->mark + studentArray[j];
                      ~~~~~~~~~~ ^ ~~~~~~~~~~~~~~~

untitled.c:86:29: warning: conversion to ‘float’ from ‘int’ may alter its value [-Wconversion]
     avg = (float)temp->mark / j;
                             ^

untitled.c: In function ‘student_update’:
untitled.c:91:27: warning: unused parameter ‘stuadd’ [-Wunused-parameter]
 void student_update(char *stuadd)
                           ^~~~~~

Compilation failed.

还有其他一些问题,例如:

free(temp);
free(temp->name);

在分配的内存已传递到free()之后,正在访问指向分配的内存的指针,结果是行为不确定。建议:

free(temp->name);
free(temp);

关于以下陈述

FILE *fptr;
fptr = fopen("stuadd.txt", "a+");
struct student *temp = (struct student *)malloc(sizeof(struct student));

if (fptr == NULL)
    printf("\nError.");

总是在调用C库函数后立即检查错误指示。

将错误消息输出到stderr,而不是stdout

当错误指示来自C库函数时,请立即调用perror();以将错误消息和系统认为发生错误的文本原因输出到stderr

当调用任何堆分配函数:malloc calloc realloc时,1)返回的类型为void*,可以分配给任何指针。强制转换只会使代码混乱,使其更难以理解,调试等。2)始终检查(!= NULL)返回值以确保操作成功。建议:

FILE *fptr;
fptr = fopen("stuadd.txt", "a+");

if ( !fptr )
{
    perror("fopen failed");
    exit( EXIT_FAILURE );
}

// implied else, fopen successful

struct student *temp = malloc(sizeof(struct student));
if( !temp )
{
    perror( "malloc failed" );
    exit( EXIT_FAILURE );
}

// implied else, malloc successful

关于:

scanf(" %[^\n]s", temp->name);

scanf()的呼叫是胡说八道。由于输入格式说明符%[^\n]在遇到换行符时将停止来自stdin的输入,因此stdin中的下一个字符不可能为s调用scanf()系列函数中的任何一个,请始终检查返回的值以确保操作成功。使用输入格式说明符时,%s和/或%[...]始终包含一个MAX CHARACTERS修饰符,该修饰符比输入缓冲区的长度小1,以避免缓冲区溢出的任何可能性(以及由此产生的不确定行为) 。建议删除格式字符串中的结尾s,然后检查返回值并限制可输入的字符总数,如:

 if( scanf(" %29[^\n]", temp->name) != 1 )
 {
     fprintf( stderr, "scanf failed to input the student name\n" );
     exit( EXIT_FAILURE );
 }

关于:

for(j = 0; j < 100; j++)
{
    temp->mark = temp->mark + studentArray[j];
}

没有数组studentArray[],因此永远不会产生预期的结果。

关于错误消息:

avg = (float)temp->mark / j;
  untitled.c:83:33: error: invalid operands to binary + (have ‘float’ and ‘char *’)
         temp->mark = temp->mark + studentArray[j];

当然不能将'float'值添加到char数组的指针中。您实际上想完成什么?

以上所有只是发布代码中问题的“冰山一角”。建议使用调试器并逐步检查代码以确定许多问题