我尝试用C编译这段代码,它的目的是从一个.dat文件中积累数据,其中的结构体有关于标记、年龄、性别的信息。当我编译它时,一个错误显示说“分段错误”,我写了一个printf来显示i、j和k的值;因为我认为它们是问题所在,下面是代码和失败的照片:`
#include <stdio.h>
#include <conio.h>
#include <stdlib.h>
#include <time.h>
#include <windows.h>
struct persona {
int edad; //EDAD DE 12-65//
int notas; //NOTAS DE 0-10//
char sexo; //SEXO 1=MASCULINO Y 2=FEMENINO//
char exi; //EXI 1=SI 2=NO
};
struct reg {
int notas;
int contex;
int cont;
};
const int imax = 7;
const int jmax = 6;
const int kmax = 3;
struct reg A[imax][jmax][kmax];
void retardo() {
for(int i=0; i < 11000; i++) {
for(int j=0; j < 11000; j++) {
}
}
}
void processbar() {
system("pause");
system("cls");
int i, j;
for(i=0; i < 20 ; i++) {
printf("Cargando... \n");
printf("====================\n");
for(j=0; j < i ; j++) {
printf("X");
}
printf("\n====================\n");
retardo();
system("cls");
}
}
void etario(int j, char grupoed[10]) //ASIGNAMOS LOS RANGOS ETARIOS//
{
switch(j)
{
case(1):
grupoed ="12-15";
break;
case(2):
grupoed ="16-25";
break;
case(3):
grupoed ="26-35";
break;
case(4):
grupoed ="36-45";
break;
case(5):
grupoed ="46-55";
break;
case(6):
grupoed = "56-65";
default:
printf("\nHa ocurrido un error");
}
}
void grupoed(struct persona p, int j) {
if( p.edad < 12) {
printf("\nexiste un error en la edad");
}
if(p.edad < 16) {
j = 1;
}
if(p.edad < 26) {
j = 2;
}
if(p.edad < 36) {
j = 3;
}
if(p.edad < 46) {
j = 4;
}
if(p.edad < 56) {
j = 5;
}
if(p.edad < 66) {
j = 6;
}
else {
printf("\nexists un error en la edad");
}
}
void niveling(struct persona p, int i) {
if(p.notas < 2) {
i = 1;
}
if(p.notas < 4) {
i = 2;
}
if(p.notas < 6) {
i = 3;
}
if(p.notas < 8) {
i = 4;
}
if(p.notas < 10) {
i = 5;
}
}
void femasc(struct persona p, int k) {
if(p.sexo = 'M') {
k = 1;
}
else {
if(p.sexo = 'F') {
k = 2;
}
}
}
void matrizcero(struct reg A[imax][jmax][kmax], int i, int j, int k) {
for (i = 1; i < 7; i++)
{
for (j = 1; i < 6; j++)
{
for (k = 1; i < 3; k++)
{
A[i][j][k] = {0,0,0};
}
}
}
}
int main() {
struct reg A[imax][jmax][kmax];
void processbar();
void matrizcero(struct reg A[imax][jmax][kmax], int i, int j, int k);
struct persona p;
struct reg;
int i, j, k,rangomay, rangomen, rangointmay, resmay, resmen, jex, jmay, jmen, NIV, GRUPOET, sexo, cantidadM, califM, cantidadF, califF, grupoetario;
char grupoed[10];
float prom_m, prom_f;
FILE *entrada; //ABRO ARCHIVO
entrada=fopen("datospersonas.dat","rb");
if (entrada == NULL){
exit(1);
printf("\nError al abrir el archivo");
}
else {
printf("\nArchivo abierto exitosamente!");
}
while(!(feof(entrada))){
void niveling(struct persona p, int i);
void grupoedad(struct persona p, int j);
void femasc(struct persona p, int k);
printf("\n%d",i);
printf("\n%d",j);
printf("\n%d",k);
A[i][j][k].notas = A[i][j][k].notas + p.notas;
A[i][j][k].cont = A[i][j][k].cont;
if(p.exi = 'S') {
A[i][j][k].contex = A[i][j][k].contex + 1;
}
fread(&p,sizeof(p),1,entrada); //LEO ARCHIVO
}
for(i = 1; i < 6; i++) { //TOTALIZO HOMBRES Y MUJERES
for(j = 1; i < 7; i++) {
A[i][j][3].notas = A[i][j][3].notas + A[i][j][2].notas;
A[i][j][3].cont = A[i][j][3].cont + A[i][j][2].cont;
A[i][j][3].contex = A[i][j][3].contex + A[i][j][2].contex;
}
}
for(j = 1; j < 7; j++) {
for(i = 1; i < 6; i++) {
cantidadM = cantidadM + A[i][j][1].cont;
califM = califM + A[i][j][1].notas;
}
}
prom_m = califM / cantidadM; //PROMEDIO DE CALIFICACIONES DE LOS HOMBRES
for(j = 1; j < 7; j++) {
for(i = 1; i < 6; i++) {
cantidadF = cantidadF + A[i][j][2].cont;
califF = califF + A[i][j][2].notas;
}
}
prom_f = califF / cantidadM; //PROMEDIO DE CALIFICACIONES MUJERES
for(k = 1; k < 3; k++) {
for(i = 1; i < 6; i++) {
for(j = 1; j < 7; j++) {
A[6][j][k].cont = A[6][j][k].cont + A[i][j][k].cont;
A[6][j][k].contex = A[6][j][k].contex + A[i][j][k].cont;
A[6][j][k].notas = A[6][j][k].notas + A[i][j][k].notas;
}
}
}
for(j = 1; j < 7; j++) {
A[6][j][3].cont = A[6][j][1].cont + A[6][j][2].cont;
A[6][j][3].cont = A[6][j][1].contex + A[6][j][2].contex;
A[6][j][3].notas = A[6][j][1].notas + A[6][j][2].notas;
}
resmay = A[6][1][3].contex;
for(j = 1; j < 7; j++) {
if(A[6][j][3].contex > resmay) {
resmay = A[6][j][3].contex;
jex = j;
}
}
for(k = 1; k < 3; k++) {
for(j = 1; j < 7; j++) {
A[7][j][k].notas = A[6][j][k].notas / A[6][j][k].cont;
}
}
resmen = A[7][1][3].notas;
resmay = A[7][1][3].notas;
for(j = 1; j < 7; j++) {
if(A[7][j][3].notas > resmay) {
resmay = A[7][j][3].notas;
jmay = j;
}
else {
if(A[7][j][3].notas < resmen) {
resmen = A[7][j][3].notas;
jmen = j;
}
}
}
void etario(int jmay);
printf("\nEl rango etario con mayor calificacion en promedio fue el comprendido entre: %s", grupoed, " años");
void etario(int jmen);
printf("\nEl rango etario con menor calificacion en promedio fue el comprendido entre: %s", grupoed, " años");
printf("\nEl promedio de calificaciones en femeninos fue: %f", prom_f);
printf("\nEl promedio de calificaciones en masculinos fue: %f", prom_m);
void etario(int jex);
printf("\nEl rango etario con mayor interes en rendir examenes internacionales es el comprendido entre: %s", grupoed, "años");
fclose(entrada);
system("pause");
return 0;
}
一个
为了以防万一,下面是生成.dat文件的文件...
`
#include <stdio.h>
#include <conio.h>
#include <stdlib.h>
#include <time.h>
struct persona {
int edad; //EDAD DE 12-65//
int notas; //NOTAS DE 0-10//
char sexo; //SEXO 1=MASCULINO Y 2=FEMENINO//
char exi; //EXI 1=SI 2=NO
};
void generacion()
{
FILE *entrada;
entrada=fopen("datospersonas.dat","w+");
if (entrada == NULL){
exit(1);
}
fclose(entrada);
}
int main()
{
int s;
int exi;
generacion();
persona p;
FILE* entrada;
entrada=fopen("datospersonas.dat","w+");
for (size_t i=0;i<30; i++)
{
p.edad =(rand() %53)+12;
p.notas =(rand() %9)+1;
s=(rand() %2)+1;
if(s == 1){
p.sexo='M';
}
else{
p.sexo='F';
}
exi=(rand() %2)+1;
if(exi == 1){
p.exi='S';
}
else{
p.exi='N';
}
fwrite(&p, sizeof(struct persona),1,entrada);
printf("edad: %d\n",p.edad);
printf("nota: %d\n",p.notas);
printf("sexo: %c\n",p.sexo);
printf("esta interesado en rendir examenes internacionales: %c\n",p.exi);
}
fclose(entrada);
return 0;
}
`
我已经尝试写打印,也处理较少的结构体,我开始编译500个结构体,现在我试图做它与不到50...
1条答案
按热度按时间dvtswwa31#
显示的代码有两个主要问题:
1.如何调用函数?
通过调用函数名称,后跟参数列表来调用函数。
这是
是呼叫
fread
函式的范例。这些
并且这些
是function declarations的例子。它们让编译器知道一个函数存在,它接受什么类型的参数,以及它返回什么类型的值。通常你会在文件的顶部找到这些(通常称为 * 转发声明 *),或在头文件中(其中函数是在单独的源文件中 * 定义 * 的)。这使得其他函数所依赖的函数在定义之前就公开了它们的存在。
例如:
如果没有
foo
的初始声明,bar
将不知道foo
接受什么类型的自变量,以及它返回什么类型的值。1.如何从函数中检索数据。
C语言是一种完全 * 按值传递 * 的语言。这意味着函数接收作为参数给出的值的 * 副本 *。有时函数接受指针作为参数,但那些 * 指针值 * 仍然是副本。它是使用间接与指针值,使C模仿在其他语言中发现的 * 按引用传递 * 行为。
函数参数在函数中被视为 * 局部变量 *。更改函数参数的值不会更改调用方的scope中任何变量的值。具有相同名称但在不同作用域中的变量不会引用同一对象。
例如,这个程式会先打印
0
,然后再打印1
。如果
foo
在调用者的作用域中更改了a
,它将打印0
,然后打印0
,但我们看到情况并非如此。从一个函数中检索数据的主要方法是使用它的返回值。一个函数可以使用
return
关键字向它的调用者返回一个值。例如,可以将
niveling
更改为返回int
:此函数随后用作:
非
void
函数必须始终返回适当类型的值。对于
etario
,使用数组参数调用它是正确的,但必须使用strcpy
将字符串文字的内容复制到数组中。使用上述信息修复程序后,仍然存在一些关键问题。
您的主循环格式不正确,因为
fread
只在循环的 * 结尾 * 调用,而它应该在循环的开头调用。您还需要检查fread
的返回值是否等于预期的字节数(sizeof p
),否则p
不是未初始化就是不确定的,使用它的值肯定会调用Undefined Behaviour。另请参阅:Why is “while( !feof(file) )” always wrong?
越界访问:如果
jmax
是6
,则A
数组的第二维中的最后一个有效索引是5
。数组
A
的访问超出界限的情况有几种,例如,以及您使用了
i
而不是j
,或一些类似的印刷错误:如果你创建了
imax
、jmax
和kmax
这样的“常量”,那么你应该在整个代码中使用它们,而不是在所有地方都使用幻数。示例:
您也会遇到语法问题,例如:
=
是指派运算子。==
是相等运算子。结论:一个好的编译器加上足够的警告级别会对你有很大的帮助,所以你应该把你的编译器警告级别调高。对于MSVC,至少使用
/W4
或/Wall
,也可能使用/Wx
来强制更好的编码实践。请参见:Warning levels。你还需要更仔细地学习这门语言。考虑学一门好的C textbook。