名称和姓氏搜索功能将不起作用。为什么?

时间:2015-01-01 21:25:39

标签: c function

我创建了一个函数作为我的项目,名称搜索/姓氏搜索功能不起作用并给出运行时错误。我无法真正看到错误。那有什么不对呢?

ID和Mark搜索系统也有一些错误,每当你搜索一个ID时它也会带来mark = 0,如果你搜索Mark,它也会带来ID = 0.

完整代码:

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

struct Student
{
    long long int id;
    char firstname[20];
    char lastname[20];
    int mark;
} student;

void
storeRecord()
{
    FILE *fp;

    printf("\nEnter Student Details:\n\nID number: ");
    scanf_s("%lld",&student.id);

    printf("\nName:");
    scanf_s("%19s",student.firstname);

    printf("\nSurname:");
    scanf_s("%19s",student.lastname);

    printf("\nMark(0 - 100 integer) : ");
    scanf_s("%d",&student.mark);

    fp = fopen("studentfile.txt","a+"); /* check if the file was opened */
    if (fp == NULL)
        return;
    fprintf(fp, "\n%lld\t%s\t%s\t%d\t", 
        student.id, 
        student.firstname, 
        student.lastname, 
        student.mark);
    fclose(fp);

    printf("A student record has been added successfully...\n");
    getchar();
}

int
compareStudentsById(struct Student lhs, struct Student rhs)
{
    return (lhs.id == rhs.id);
}

int
compareStudentsByName(struct Student lhs, struct Student rhs)
{
    return (strcmp(lhs.firstname, rhs.firstname) == 0);
}

int
compareStudentsByLastame(struct Student lhs, struct Student rhs)
{
    return (strcmp(lhs.lastname, rhs.lastname) == 0);
}

int
compareStudentsByMark(struct Student lhs, struct Student rhs)
{
    return (lhs.mark == rhs.mark);
}

void
printStudent()
{
    printf("\nThe record is found.\n");
    printf("\nID: %lld\nName: %s\nSurname: %s\nMark: %d \n",
        student.id,
        student.firstname,
        student.lastname,
        student.mark
    );
}

void
searchStudent(int(*compare)(struct Student,struct Student), const char *const name, const char *const lastname, long long int id, int mark)
{
    FILE *fp;
    int   found;
    int   matches;


    if (name != NULL)
        printf("Searching record with Name = %s.\n", name);
    if (lastname != NULL)
        printf("Searching record with Surname = %s.\n", lastname);
    if (id != -1)
        printf("Searching record with ID   = %lld.\n", id);
    if (mark != -1)
        printf("Searching record with Mark   = %d.\n", mark);

    found = 0;
    fp    = fopen("studentfile.txt", "r");
    if (fp == NULL)
    {
        printf("IO error\n");
        return;
    }

    do
    {
        struct Student other;

        if (name != NULL)
            strcpy(other.firstname, name);
        if (lastname != NULL)
            strcpy(other.lastname, lastname);

        other.id = id;
        other.mark = mark;
        matches  = fscanf(fp,"\n%lld\t%s\t%s\t%d\t", 
            &student.id, 
            student.firstname, 
            student.lastname, 
            &student.mark);

        if (matches == 4)
            found = (compare(student, other) != 0);

    } while ((matches == 4) && (found == 0));

    if (found != 0)
        printStudent(); 
    else
        printf("Not found...\n");

    getchar();
}

void
searchStudentByName()
{
    char studentname[20];

    printf("\nEnter student first name: ");
    scanf_s("%19s", studentname);

    searchStudent(compareStudentsByName, studentname, NULL, NULL, NULL);
}

void
searchStudentById()
{
    long long int id;

    printf("\nEnter ID: ");
    scanf_s("%lld", &id);

    searchStudent(compareStudentsById, NULL, NULL, id, NULL);
}

void
searchStudentByLastname()
{
    char studentlastname[20];

    printf("\nEnter student surname: ");
    scanf_s("%19s", &studentlastname);

    searchStudent(compareStudentsByLastame, NULL, studentlastname, NULL, -1);
}

searchStudentByMark()
{
    int mark;

    printf("\nEnter Mark: ");
    scanf_s("%d", &mark);

    searchStudent(compareStudentsByMark, NULL, NULL, NULL, mark);
}

int main()
{

    int choice;

    choice = 0;
    while (choice != 5)
    {
        printf("\n\tC PROGRAM OF STUDENT DATABASE SYSTEM"); 
        printf("\n1 -> Store a new record in database\n");
        printf("2 -> Search a student record by Student First Name\n");
        printf("3 -> Search a student record by ID\n");
        printf("4 -> Search a student record by Surname\n");
        printf("5 -> Search a student record by Mark\n");
        printf("6 -> Quit Student Database");
        printf("\n\n");
        printf("Enter your choice : ");

        scanf_s("%d",&choice);
        switch(choice)
        {
        case  1:
            storeRecord();
            break;
        case 2:
            searchStudentByName();
            break;
        case 3:
            searchStudentById();
            break;
        case 4:
            searchStudentByLastname();
            break;
        case 5:
            searchStudentByMark();
            break;
        }
    }
    getch();
    return 0;
}

2 个答案:

答案 0 :(得分:0)

如果您已经编译了此代码,并且警告已打开(正如每个人都应该这样做)并修复了警告,那么这个(修改过的)程序将大部分工作。通过Mark搜索工作但结束程序。我会把它留给你解决的问题。

void
printStudent()
{
    printf("\nThe record is found.\n");
    printf("\nID: %lld\nName: %s\nSurname: %s\nMark: %d \n",
        student.id,
        student.firstname,
        student.lastname,
        student.mark
    );
}

void
searchStudent(int(*compare)(struct Student,struct Student), const char *const name, const char *const lastname, long long int id, int mark)
{
    FILE *fp;
    int   found;
    int   matches;


    if (name != 0)
        printf("Searching record with Name = %s.\n", name);
    if (lastname != 0)
        printf("Searching record with Surname = %s.\n", lastname);
    if (id != -1)
        printf("Searching record with ID   = %lld.\n", id);
    if (mark != -1)
        printf("Searching record with Mark   = %d.\n", mark);

    found = 0;
    fp    = fopen("studentfile.txt", "r");
    if (fp == 0)
    {
        printf("IO error\n");
        return;
    }

    do
    {
        struct Student other;

        if (name != NULL)
            strcpy(other.firstname, name);
        if (lastname != NULL)
            strcpy(other.lastname, lastname);

        other.id = id;
        other.mark = mark;
        matches  = fscanf(fp,"\n%lld\t%s\t%s\t%d\t", 
            &student.id, 
            student.firstname, 
            student.lastname, 
            &student.mark);

        if (matches == 4)
            found = (compare(student, other) != 0);

    } while ((matches == 4) && (found == 0));

    if (found != 0)
        printStudent(); 
    else
        printf("Not found...\n");

    getchar();
}

void
searchStudentByName()
{
    char studentname[20];

    printf("\nEnter student first name: ");
    scanf("%19s", studentname);

    searchStudent(compareStudentsByName, studentname, 0, 0, 0);
}

void
searchStudentById()
{
    long long int id;

    printf("\nEnter ID: ");
    scanf("%lld", &id);

    searchStudent(compareStudentsById, 0, 0, id, 0);
}

void
searchStudentByLastname()
{
    char studentlastname[20];

    printf("\nEnter student surname: ");
    scanf("%19s", studentlastname);

    searchStudent(compareStudentsByLastame, 0, studentlastname, 0, -1);
}

searchStudentByMark()
{
    int mark;

    printf("\nEnter Mark: ");
    scanf("%d", &mark);

    searchStudent(compareStudentsByMark, 0, 0, 0, mark);
}

int main()
{

    int choice;

    choice = 0;
    while (choice != 5)
    {
        printf("\n\tC PROGRAM OF STUDENT DATABASE SYSTEM"); 
        printf("\n1 -> Store a new record in database\n");
        printf("2 -> Search a student record by Student First Name\n");
        printf("3 -> Search a student record by ID\n");
        printf("4 -> Search a student record by Surname\n");
        printf("5 -> Search a student record by Mark\n");
        printf("6 -> Quit Student Database");
        printf("\n\n");
        printf("Enter your choice : ");

        scanf("%d",&choice);
        switch(choice)
        {
        case  1:
            storeRecord();
            break;
        case 2:
            searchStudentByName();
            break;
        case 3:
            searchStudentById();
            break;
        case 4:
            searchStudentByLastname();
            break;
        case 5:
            searchStudentByMark();
            break;
        case 6: 
            goto lend;
        }
    }
lend:;
    return 0;
}

提示:向default添加包含错误消息的switch(choice)子句,并将if (choice != 5)更改为更好的测试。

答案 1 :(得分:0)

扫描像scanf_s("%19s", ...);这样的字符串的多次使用都不正确。

  1. 请勿使用&amp;在studentlastname之前。

  2. 同时传递缓冲区的大小。这是scanf()scanf_s()之间的主要区别:为char *参数传递的大小。如果没有适当的参数,可能会发生seg故障或其他奇怪的行为。

  3. 检查scanf_s()

    的结果
    char studentname[20];
    // scanf_s("%19s", &studentlastname);
    if (1 != scanf_s("%s", studentlastname, sizeof studentlastname)) {
      Handle_Error();
    }
    
  4. IMO:不要对任何用户输入使用scanf()scanf_s()。而是使用fgets()sscanf()sscanf_s()

    char studentname[20];
    char buffer[2 * sizeof studentname + 2];  // I like 2x buffers
    if (fgets(buffer, sizeof buffer, stdin) == NULL) {
      Handle_EOF();
    } 
    if (1 != sscanf("%19s", studentlastname)) {
      Handle_Error();
    }
    // or
    if (1 != sscanf_s("%s", studentlastname, sizeof studentlastname)) {
      Handle_Error();
    }
    
  5. 如果以这种方式更改所有用户输入,包括获取数字的用户输入,则从scanf()更改为fgets()确实效果最佳。

    1. int main() - &gt; int main(void) @Dirk Koopman

    2. 如果您的环境需要最终的getch(),请考虑删除它。

    3. BTW良好的退出策略,检查matches = fscanf(fp,...的结果,好的代码没有使用feof()