C 编程 - 使用并行数组输入名称、练习分数和计算练习分数的平均值并显示

C Programming - Using Parallel Arrays to enter Names, Exercise Marks and Compute Average of Exercise Marks and Display

我正在自学C编程,同事推荐了下面的C程序进一步学习,可以输入姓名和年龄,显示和使用Insert,Delete,Display和退出菜单选项。

我正在尝试将其转换为我当前的学习流逻辑场景,我需要输入名称、练习标记 1(最多 3 个),然后计算平均值并在使用插入时显示,删除、显示、更新(只更新乐谱,不更新名字)、删除、退出。

任何关于如何学习此代码和理解逻辑并将其应用于第二个场景的指导将不胜感激。

代码如下:

#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#define MAX 50
//using parallel arrays as fields in the list
typedef struct list{
    char name[MAX][31];
    int age[MAX];
    int last;
}LIST;
LIST L;//L structure is global

void save();
void retrieve();
void makenull();
void insert(char n[31],int a);
void del(char n[31]);
void display();
int locate(char n[31]);
int isfull();
int isempty();
int menu();

int main(){
char nm[31];
int ag;
makenull();
retrieve();
while(1){
    switch(menu()){
    case 1: system("cls");printf("Insert Mode\n");
            printf("Input Name: ");scanf("%s",nm);
            printf("Input Age: ");scanf("%d",&ag);insert(nm,ag);break;
    case 2: system("cls");printf("Delete Mode\n");
            printf("Input Name: ");scanf("%s",nm);del(nm);break;
    case 3: display();break;
    case 4: save();exit(0);
    default: printf("\n1-4 lang!\n");system("pause");
    }
}
return 0;
}
void makenull(){
   L.last = -1;
}
void insert(char n[31],int a){
if (isfull()){
    printf("List is full.\n");
    system("pause");
}
else {
    L.last++;
    strcpy(L.name[L.last],n);
    L.age[L.last]=a;
}

}
void del(char n[31]){
int p;
if (isempty()){
    printf("List is empty.\n");
    system("pause");
}
else {
    p=locate(n);
    if (p==-1){
        printf("Not found.\n");
        system("pause");
    }
    else{
        for(int i = p;i<L.last;i++){
            strcpy(L.name[i],L.name[i+1]);
            L.age[i]=L.age[i+1];
        }
        L.last--;
        printf("Successful delete operation.\n");
        system("pause");
    }
  }
}
void display(){
int i;
system("cls");
printf("  Name     Age \n");
for(i=0;i<=L.last;i++)
    printf("%d.) %s     %d\n",i+1,L.name[i],L.age[i]);
system("pause");
}
int locate(char n[31]){
int i;
for (i=0;i<=L.last;i++)
    if(strcmp(L.name[i],n)==0)
         return i;
return -1;
}
int isfull(){
  if (L.last==MAX-1)
    return 1;
  else
    return 0;
}
int isempty(){
  return(L.last==-1);
}
int menu(){
int op;
system("cls");
printf("MENU\n");
printf("1. Insert\n");
printf("2. Delete\n");
printf("3. Display\n");
printf("4. Exit\n");
printf("\nSelect(1-4): ");
scanf("%d",&op);
return(op);
}
void save(){
FILE *fp;
int i;
fp=fopen("Practice4.dbf","w+");
if (fp==NULL){
    printf("File Error.\n");
    system("pause");
}
else{
    for (i=0;i<=L.last;i++)
        fprintf(fp,"%s %d\n",L.name[i],L.age[i]);
}
fclose(fp);
}
void retrieve(){
FILE *fp;
char n[31];
int i,a;
fp=fopen("Practice4.dbf","r+");
if (fp==NULL){
    printf("File Error.\n");
    system("pause");
}
else {
    while(!feof(fp)){
        fscanf(fp,"%s %d\n",n,&a);
        insert(n,a);
    }

}
  fclose(fp);
}

您的代码格式不正确,没有评论。我不能用一些代码直接给你答案,但总结我所有的评论(当然我删除了它们),这就是我要说的:

考虑这个场景-

if your .dbf has more than MAX 50 elements, then your while (!feof(fp)) inside retrieve() will keep calling insert() and insert() will keep executing its if () { } block.

您应该添加 while (!feof(fp) && L.last < MAX) 之类的内容来防止出现这种情况,并且您需要进一步修改 insert() 中的代码。另一件事是,此代码没有任何 update() 函数和 scores 变量。您需要在 struct 中添加 scores 并且 .dbf.

中必须有 scores 字段

现在,让我们暂时假设您的代码中的其他一切都很好,那么您应该按照以下步骤操作:

  • 声明变量
char nameInput[31];
float ex_marks[3], sum = 0, avr = 0;

main().

  • main() 内的 switch () 块中添加另一个 case 5 并将以下 伪代码 翻译并转换为 C 代码:
  1. nameInput
  2. 中阅读name
  3. locate()
  4. 如果找到的话 3.a 对于 i = 02ex_marks[i] 中阅读 marks sum = sum + ex_marks[i] 3.b 计算 avr = sum / 3 3.c 显示 nameavr
  5. 其他 显示 name 不在列表中。
  6. 退出

另请参阅 why is while(!feof()) always wrong?