我正在开发一个会生成并列出学校记录的应用程序。但是每次运行时,它都会不断给我
非法指示: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;
}
答案 0 :(得分:2)
我相信我能够重现您的问题。当我在Microsoft编译器上运行代码时,出现“运行时检查失败#4”,抱怨可变长度数组附近的堆栈损坏。我可以通过将char Age[2];
更改为char Age[3];
来为终止空字符添加空格来解决此问题,正如其他人在评论部分中所暗示的那样。
问题在于,以下行无法访问所有三个数组:
sprintf(sdv[i].Age, "%d", ages[ageNum]);
sdv
,因为i在[0..numOfStudents]范围内,但它应该在[0..numOfStudents-1]范围内。可以通过将行for(int i = 0;i <= numOfStudents;i++){
替换为for(int i = 0;i < numOfStudents;i++){
来解决此问题。sdv[i].Age
。该数组被声明为长度为2的char数组。但是,最大字符串长度为3。例如,字符串“ 14”要求长度为3的char数组用于存储,因为它还需要空格来终止空字符。可以通过在学生结构的声明中将行char Age[2];
替换为char Age[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。因此,您实际上有一个无限循环,使得不可能从主菜单退出程序。