【问题标题】:Searching for a match in a structure array在结构数组中搜索匹配项
【发布时间】:2016-03-31 01:22:22
【问题描述】:

我已经在这个烂摊子上混了一段时间,但我仍然没有弄清楚我哪里出了问题,如果它像指针这样荒谬的话,我会完全自欺欺人。

显示的任务:尝试用学生 ID、姓名、姓氏、出生日期和成绩填充结构数组。然后通过提供给用户的匹配 ID 进行搜索。

我非常感谢与此主题相关的任何帮助,我已经严重坚持了一段时间。另外我提前为法语部分道歉

// Part 1
struct Date{
    int day;
    int month;
    int year;
};

// Part 2
struct Student{
    int ID;
    char name[20];
    char lastname[20];
    struct Date DOB;
    int notes[J];
};

// Part 3
void FillStudentList(struct Student E){
    int i;
    printf("\nInsert ID: ");
    scanf("%d", &E.ID);
    printf("Insert name: ");
    scanf("%s", &E.name);
    printf("Insert last name: ");
    scanf("%s", &E.lastname);
    printf("Insert date of birth: ");
    scanf("%d %d %d", &E.DOB.day, &E.DOB.month, &E.DOB.year);
    printf("Insert notes: ");
    for(i=0; i<J; i++)
        scanf("%d", &E.Notes[i]);
}

// Part 4
void ShowByNb(int Nb, struct Student E[], int NbStudents){
    int j, i;
    for(i=0; i<NbStudents; i++){
        if (E[i].ID== Nb){
            printf("\nID: %d", E[i].ID);
            printf("\nName: %s", E[i].name);
            printf("\nLast Name: %s", E[i].lastname);
            printf("\nDate Of Birth: %s-%s-%s", E[i].DOB.day, E[i].DOB.month, E[i].DOB.year);
            printf("\nNotes: ");
            for(j=0; j<J; j++){
                printf("%d", E[i].Notes[j]);
            }
        }
        else
            printf("\nInvalid Student!\n");
    }
}

// Part 5
void main(){
    int i, x;
    struct Student E[N];
    for(i=0; i<N; i++){
        printf("\n\nStudent #%d", i+1);
        FillStudentList(E[i]);
    }

    printf("\n\nSearch student by NB: ");
    scanf("%d", &x);
    ShowByNb(x, E, N);
    } 

【问题讨论】:

  • 你得到的输出是什么?请为您的变量和函数使用更好的名称。
  • Dat 的元素是int,但您使用%s 而不是%d 来阅读它们。那是行不通的。
  • @ViniciusZaramella 抱歉,这是一个法国项目,所以这就是为什么名称是法语的原因。我得到的输出是“无效的学生!”当我尝试进行应该有效的搜索时。它被写了两次。编辑:我修好了
  • @Barmar 对不起,我复制了旧版本的代码,我确实将 %s 修改为 %d,但它仍然无法正常工作。
  • @Barmar,我指的是长度为 1 或 2 位的变量......如 E、x、Nb。这只是一种不好的做法,会使您的代码难以阅读。

标签: c arrays structure


【解决方案1】:

我相信,下面的编辑代码可以实现您的目标。主要问题(除了使用 '%s' 读取/打印 'int' 之外,是如何将结构传递给函数。有必要通过引用传递结构,以便在 FillStudentList 函数之外可以看到它的值;请参阅此link.

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

#define N 2
#define J 2

// Part 1
struct Dat{
    int jour;
    int mois;
    int annee;
};

// Part 2
struct Etudiant{
    int numero;
    char nom[20];
    char prenom[20];
    struct Dat DDN;
    int Notes[J];
};

// Part 3
/* Modified this so that a pointer to the struct is passed instead of a copy of the struct */
void FillStudentList(struct Etudiant *E){
    int i;
    printf("\nInsert ID: ");
    scanf("%d", &E->numero);
    printf("Insert name: ");
    scanf("%s", E->nom);
    printf("Insert last name: ");
    scanf("%s", E->prenom);
    printf("Insert date of birth: ");
    /* These are integers. Do not read with %s */
    scanf("%d %d %d", &E->DDN.jour, &E->DDN.mois, &E->DDN.annee);
    printf("Insert notes: ");
    for(i=0; i<J; i++)
        scanf("%d", &E->Notes[i]);
}

// Part 4
void ShowByNb(int Nb, struct Etudiant E[]){
    /* Don't redefine N == NbEtudiants making it seem that N is variable */
    int j, i;
    for(i=0; i<N; i++){
        if (E[i].numero == Nb){
            printf("\nID: %d", E[i].numero);
            printf("\nName: %s", E[i].nom);
            printf("\nLast Name: %s", E[i].prenom);
            /* Again, can't print integers with %s */
            printf("\nDate Of Birth: %d-%d-%d", E[i].DDN.jour, E[i].DDN.mois, E[i].DDN.annee);
            printf("\nLes notes: ");
            for(j=0; j<J; j++){
                printf("%d ", E[i].Notes[j]);
            }
            return;
        }
        /* Your previous else would print invalid student every time you ran through the loop even 
         * if the student number was valid for a later student.
         */
    }
    /* Only print this if student was not found in any of the N Student structures */
    printf("\nInvalid Student!\n");
}

// Part 5
void main(){

    setbuf(stdout, NULL);

    int i, x;
    struct Etudiant E[N];

    for(i=0; i<N; i++){
        printf("\n\nStudent #%d", i+1);
        FillStudentList(&E[i]);
    }

    printf("\n\nSearch student by NB: ");
    scanf("%d", &x);
    ShowByNb(x, E);
}

输入

1 1 1 1 1 1 1 1 2 2 2 2 2 2 2 2 2

输出

Student #1
Insert ID: 1
Insert name: 1
Insert last name: 1
Insert date of birth: 1
1
1
Insert notes: 1
1


Student #2
Insert ID: 2
Insert name: 2
Insert last name: 2
Insert date of birth: 2
2
2
Insert notes: 2
2


Search student by NB: 2

ID: 2
Name: 2
Last Name: 2
Date Of Birth: 2-2-2
Les notes: 2 2

【讨论】:

  • 感谢回复,但问题依旧。我试过这样做,我得到错误“错误C2232:'-> nom':左操作数有'struct'类型,使用'。' "
  • 您可以尝试复制我发布的确切代码吗?它对我有用。我已经更新了答案以包括输入和代码输出。
  • @PZwan 您的代码仍有一些错误。在scanf("%s", &amp;E-&gt;nom); 中,scanf 期待char *,但您使用的是char (*)[20]scanf("%s", &amp;E-&gt;prenom); 也一样,应该是 scanf("%s", E-&gt;nom);scanf("%s", E-&gt;prenom);
  • @SSC 谢谢。我做了更改。
【解决方案2】:

经典错误:按值而不是按引用传递参数:

void FillStudentList(struct Student E){
.....
}

这里发生的是在堆栈上创建结构的本地副本,填充输入的任何内容,并在函数退出时销毁。

一般在C中,即使不想修改结构体,也通过指针传递结构体参数;如果按值传递它们,则结构的每个成员都会被复制到堆栈中...这是浪费时间和内存。

因此更改函数原型(以及使用新签名的代码)应该可以解决问题:

void FillStudentList(struct Student *E){
....
}

【讨论】:

    猜你喜欢
    • 2021-11-16
    • 1970-01-01
    • 1970-01-01
    • 2019-09-16
    • 1970-01-01
    • 2016-09-18
    • 1970-01-01
    • 2020-04-28
    • 1970-01-01
    相关资源
    最近更新 更多