arrays - 如果 struct 中的字符大小为 30 或更大,则程序终止
问题描述
头文件 - 如果我将 char 大小从 30 更改为 20 或更少,代码可以正常工作,但如果它的 30 或更高,它不会在主代码中的第 5 种情况的 for 循环之后执行。
struct Data
{
int Emp_id;
char Emp_name[30];
char Emp_city[30];
};
void input(struct Data emp[], int n)
{
for (int i = 0; i < n; i++)
{
printf("enter employee id of %d employee: \n", i + 1);
scanf("%d", &emp[i].Emp_id);
fflush(stdin);
printf("enter employee name of %d employee: \n", i + 1);
gets(emp[i].Emp_name);
fflush(stdin);
printf("enter employee city of %d employee: \n", i + 1);
gets(emp[i].Emp_city);
}
}
主代码-添加函数在第 5 种情况下执行,如果头文件结构中的字符大小为 30 或更多,则循环停止。如果我少做一次迭代,那么代码也可以工作 - for(int i=n-5;i<n-1;i++) 但包括最后一次迭代会终止程序并且显示函数不执行。
#include <stdio.h>
#include <string.h>
#include "data.h"
void find(struct Data emp[], int n);
void sortid(struct Data emp[], int n);
void sortAlp(struct Data emp[], int n);
void count(struct Data emp[], int n);
void add(struct Data emp[], int n);
void display(struct Data emp[], int n);
int main(void)
{
int n;
int a;
printf("enter the number of employees:\n");
scanf("%d", &n);
struct Data emp[n];
input(emp, n);
printf("enter the operation you want to perform:\n");
printf("1 - to find employee record from employee id\n");
printf("2 - to sort employee record on basis of employee id\n");
printf("3 - to alphabetically sort array of characters\n");
printf("4 - to count the number of employees in database\n");
printf("5 - to add 5 more records\n");
scanf("%d", &a);
switch (a)
{
case 1:
find(emp, n);
break;
case 2:
sortid(emp, n);
display(emp, n);
break;
case 3:
sortAlp(emp, n);
display(emp, n);
break;
case 4:
count(emp, n);
break;
case 5:
add(emp, n);
break;
}
return 0;
}
void find(struct Data emp[], int n)
{
int a;
int count = 0;
printf("Enter the employee id: ");
scanf("%d", &a);
for (int i = 0; i < n; i++)
{
if (a == emp[i].Emp_id)
{
printf("Employee id: %d\n", emp[i].Emp_id);
printf("Employee name: %s\n", emp[i].Emp_name);
printf("Employee city: %s\n", emp[i].Emp_city);
count++;
}
}
if (count == 0)
{
printf("Employee id does not exist");
}
}
void sortid(struct Data emp[], int n)
{
int temp;
char temp2[30];
char temp3[30];
for (int i = 0; i < n; i++)
{
for (int j = i + 1; j < n; j++)
{
if (emp[i].Emp_id > emp[j].Emp_id)
{
temp = emp[i].Emp_id;
emp[i].Emp_id = emp[j].Emp_id;
emp[j].Emp_id = temp;
strcpy(temp2, emp[i].Emp_name);
strcpy(emp[i].Emp_name, emp[j].Emp_name);
strcpy(emp[j].Emp_name, temp2);
strcpy(temp3, emp[i].Emp_city);
strcpy(emp[i].Emp_city, emp[j].Emp_city);
strcpy(emp[j].Emp_city, temp3);
}
}
}
}
void sortAlp(struct Data emp[], int n)
{
int temp2;
char temp[30];
char temp3[30];
for (int i = 0; i < n; i++)
{
for (int j = i + 1; j < n; j++)
{
if (emp[i].Emp_name[0] > emp[j].Emp_name[0])
{
strcpy(temp, emp[i].Emp_name);
strcpy(emp[i].Emp_name, emp[j].Emp_name);
strcpy(emp[j].Emp_name, temp);
temp2 = emp[i].Emp_id;
emp[i].Emp_id = emp[j].Emp_id;
emp[j].Emp_id = temp2;
strcpy(temp3, emp[i].Emp_city);
strcpy(emp[i].Emp_city, emp[j].Emp_city);
strcpy(emp[j].Emp_city, temp3);
}
}
}
}
void count(struct Data emp[], int n)
{
int k;
for (int i = 0; i < n; i++)
{
k = i;
}
printf("number of employees: %d\n", k + 1);
}
void add(struct Data emp[], int n)
{
n = n + 5;
for (int i = n - 5; i < n; i++)
{
printf("enter employee id of %d employee: \n", i + 1);
scanf("%d", &emp[i].Emp_id);
fflush(stdin);
printf("enter employee name of %d employee: \n", i + 1);
gets(emp[i].Emp_name);
fflush(stdin);
printf("enter employee city of %d employee: \n", i + 1);
gets(emp[i].Emp_city);
}
//Program stops here without executing display
display(emp, n);
}
void display(struct Data emp[], int n)
{
for (int i = 0; i < n; i++)
{
printf("employee id of %d employee: %d \n", (i + 1), emp[i].Emp_id);
printf("employee name of %d employee: %s \n", (i + 1), emp[i].Emp_name);
printf("employee city of %d employee: %s \n", (i + 1), emp[i].Emp_city);
}
}
解决方案
对数组大小的依赖是一个巧合,缓冲区溢出总是发生在第 5 种情况下。
在您的程序中,您读取,然后分配一个条目n
数组。n
以后的更改n
,如果有的话(实际上没有,add
更改副本的操作)不会更改数组大小。这样,add
将数据写入数组,这是被禁止的,并且可能会使程序崩溃,或者更糟。
您需要的是动态内存分配,例如:
// create an array of n entries
struct Data *emp = malloc(n * sizeof(struct Data));
// grow it (or shrink) to new_n entries
emp = realloc(emp, new_n * sizeof(struct Data));
n = new_n;
// destroy it
free(emp);
emp = NULL; // safeguard, should be right after free
请注意,在增加数组时,您需要更改实际的emp
和n
在代码中使用的,而函数只获取副本(在 的情况下是指针的副本,而emp
不是整个数组的副本)。因此,要么main
在调用之前立即执行此操作add
,要么将其更改为接受指向这些变量的指针,让它自己完成这项工作。
推荐阅读
- javascript - javascript eventlistener 不适用于 ajax 加载的内容
- r - 创建一个函数来总结当前存储在数据框的 2 列中的成对“因素”
- c++ - 什么是初始化的子表达式
- java - 如何将 postgresql jdbc 驱动程序添加到 intellij?
- express - Express Gateway 降级导致请求出现巨大延迟
- java - 如何将 JSON 转换为 POJO Kotlin
- c# - 来自 JOIN 语句的 Sqlite 类属性
- ionic-framework - 如何在ionic 5中滚动到聊天页面的底部
- java - Android:编译CI/CD变量并在Android项目中使用
- java - Allure 是否支持 Cucumber JVM 6.0.0?