C-无效指令4

时间:2019-11-10 23:30:51

标签: c

我正在开发一个会生成并列出学校记录的应用程序。但是每次运行时,它都会不断给我

  

非法指示:4

这很烦人,不会消失。如何解决此问题?它使我整夜都无法入睡,因为我一直在整个Internet上寻找内容,却找不到解决方案。

这是我正在使用的代码,我正在考虑将其与数组结合使用

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



struct student{
    char Name[15];
    char Grade[5];
    char Age[3];
};

void GenerateStudent(int numOfStudents){

    //Setting struct
    struct student sdv[numOfStudents];

    //Setting Defult Values
    char names[50][15] = {
        "Daniel",
        "Olivia",
        "Blair",
        "Charley",
        "Tom",
        "Jim",
        "Peter",
        "Liam",
        "Tasha",
        "Marissa",
        "Alexa",
        "Ben",
        "Kylie",
        "Jasmin",
        "Jaz",
        "Merik",
        "Nathan",
        "William",
        "Lucas",
        "Mason",
        "Logan",
        "Alexander",
        "Jack",
        "Owen",
        "James",
        "Oliver",
        "Jackson",
        "Carter",
        "Ryan",
        "Matthew",
        "Emma",
        "Ava",
        "Sophia",
        "Charlotte",
        "Emily",
        "Abigail",
        "Chloe",
        "Isabella",
        "Avery",
        "Ella",
        "Lily",
        "Amelia",
        "Hannah",
        "Sofia",
        "Grace",
        "Victoria",
        "Maya",
        "Audrey",
        "Evelyn",
        "Nolan"

    };
    char grades[5][5] = {"A","B","C","D","F"};
    int ages[] = {5,6,7,8,9,10,11,12,13,14,15,16,17};

    int nameNum,gradeNum,ageNum;

    //Getting Rand seed using time
    time_t t;

    srand((unsigned) time(&t));

    for(int i = 0;i < numOfStudents;i++){
        //Generating Rand #
        nameNum = rand() % 50 + 1;
        gradeNum = rand() % 5 + 1;
        ageNum = rand() % 13;

        //Writing Values to Array
        strcpy(sdv[i].Name, names[nameNum]);
        strcpy(sdv[i].Grade, grades[gradeNum]);
        sprintf(sdv[i].Age, "%d", ages[ageNum]);
    }

    //Make sure you make a file called student_records.txt so you get the output of this app
    FILE * fpointer = fopen("school_records.txt", "a");

    printf("Writing to file...\n");

    for(int n = 0;n < numOfStudents;n++){
        //Printing Records into the file        
        fprintf(fpointer, "Name: %s     Age: %s     Avg Grade: %s\n", sdv[n].Name,sdv[n].Age,sdv[n].Grade);
    }

    //Removing the file from memory and saving changes
    printf("Done!\n");
    fclose(fpointer);
};

void mainMenu(){
    printf("---------------Main Menu---------------\n");
    printf("█████▒▒ 1.Generate Students\n");
    printf("█████▒▒ 2.Clear Records\n");
    printf("█████▒▒ 3.Exit\n");
    printf("---------------------------------------\n");
}

void genMenu(){
    printf("-------------Generate Menu-------------\n");
    printf("Enter # of records you want to make\n");
    printf("---------------------------------------\n");
}

void cleanMenu(){
    printf("--------------Clear Menu---------------\n");
    printf("Are you sure that you want to delete\nall information from the file?\n[Y]es or [N]o\n");
    printf("-------------------------------------\n");
}


int main(){
    //Declaring Variables

    //We cant leave this one unasigned just becuase it can cause an error if the use types 0
    int recordRequests = 1;
    int i,entOption;
    int exitNum = 0;
    while(exitNum == 0){
        mainMenu();
        printf("Enter Option: ");
        scanf("%d", &entOption);

        if(entOption == 1){
            printf("\n\n\n");
            genMenu();
            printf("Enter Value: ");
            scanf("%d", &recordRequests);

            GenerateStudent(recordRequests);
        }else if(entOption == 2){
            char ans;
            int loopExit = 0;
            cleanMenu();
            printf("Enter Value: ");
            scanf("&c", ans);

            if(ans == 'Y'){
                printf("Cleaning file...\n");
                FILE * fpointer = fopen("school_records.txt", "w");
                //Printing Records into the file        
                fprintf(fpointer,"");
                //Removing the file from memory and saving changes
                fclose(fpointer);
                printf("Clean sucsessful!\nReturning to menu...\n");
                loopExit = 0;
            }else if(ans == 'N'){
                    printf("Sending back to main menu...\n\n\n");
                    loopExit = 1;
                }else{
                    printf("Invalid Option Please type Y for yes or N for no\n");
                }
            }

    }

    return 0;
}

1 个答案:

答案 0 :(得分:2)

我相信我能够重现您的问题。当我在Microsoft编译器上运行代码时,出现“运行时检查失败#4”,抱怨可变长度数组附近的堆栈损坏。我可以通过将char Age[2];更改为char Age[3];来为终止空字符添加空格来解决此问题,正如其他人在评论部分中所暗示的那样。

问题在于,以下行无法访问所有三个数组

sprintf(sdv[i].Age, "%d", ages[ageNum]);

  1. 它正在访问数组sdv,因为i在[0..numOfStudents]范围内,但它应该在[0..numOfStudents-1]范围内。可以通过将行for(int i = 0;i <= numOfStudents;i++){替换为for(int i = 0;i < numOfStudents;i++){来解决此问题。
  2. 它正在超出范围访问数组sdv[i].Age。该数组被声明为长度为2的char数组。但是,最大字符串长度为3。例如,字符串“ 14”要求长度为3的char数组用于存储,因为它还需要空格来终止空字符。可以通过在学生结构的声明中将行char Age[2];替换为char Age[3];来解决此问题。
  3. 它正在访问数组ages,因为ageNum在[1..13]范围内,但它应该在[0..12]范围内。这是因为,与其他一些具有基于1的数组索引的编程语言相比,在编程语言C中,数组的索引是基于0的。可以通过将行ageNum = rand() % 13 + 1更改为ageNum = rand() % 13;来解决此问题。另外,出于相同的原因,必须从该行上方的两行中删除+1。

最有可能的是,我所说的#2导致堆栈内存损坏。但是,所有三个超出范围的数组访问都会导致undefined behavior,因此从理论上讲,其中任何一个都可能是问题。

此外,您的程序包含以下错误:

在函数main中,将值0分配给exitNum,然后设置for循环条件,以便在exitNum保持为0的情况下继续存在。但是,决不要将其他值分配给exitNum。因此,您实际上有一个无限循环,使得不可能从主菜单退出程序。