ayuda con este proyecto

Julian
30 de Mayo del 2004
tengo un problema con este programa no se que es el error que me bota despues de ejecutar se me totea el programa ya mire todo y no encuentro por donde es si alguin sabe por favor ayudenme.

//CABECERAS DEL SISTEMA
#include <iostream.h>
#include <conio.h>
#include <fstream.h>
#include <string.h>

struct reg_alumno{
char nombre_curso[15];
char documento[15];
char nombre[100];
char notas[50];
float promedio;
} estudiantes[300];


struct reg_curso{
char nombre_curso[15];
float promedio_curso;
} cursos[20];

//----------------------------------------------------------------------
//FUNCION QUE HACE EL MENU PRINCIPAL
char menu(){

char c;

clrscr();
gotoxy(15,8);
cout << "1. Agregar curso desde archivo de texto. n";
gotoxy(15,9);
cout << "2. Listar cursos ingresados o cargados. n";
gotoxy(15,10);
cout << "3. Listar estudiantes de un curso y promedios. n";
gotoxy(15,11);
cout << "4. Agregar estudiante a curso. n";
gotoxy(15,12);
cout << "5. Mostrar el Top 10 de estudiantes de todos los cursos. n";
gotoxy(15,13);
cout << "6. Guardar cursos cargados en archivo binario. n";
gotoxy(15,14);
cout << "7. Cargar cursos desde archivo binario. n";
gotoxy(15,15);
cout << "0 Salir. n";
gotoxy(15,17);
cout << " Digite su opcion: ";
c=getch();
switch(c){ //para validar que solo tome los valores utilizados y con el resto no haga nada
case '0','1','2','3','4','5','6','7':
return c;
// break;
}
}



//----------------------------------------------------------------------
//FUNCION PARA ELEVAR A UNA POTENCIA
float potencia(float base, int indice){

float res=1;

if (indice==0){
res=1;
}
else{
for (int i=1;i<=indice;i++){
res*=base;
}
}

return res;
}



//----------------------------------------------------------------------
//FUNCION PARA CONVERTIR CADENA EN FLOAT
void cadafloat(float &n, char c[]){

int punto=-1;

//hallar la posicion del punto
for (int i=0;i<strlen(c);i++){
if (c[i]=='.')
punto=i;
}

char entera[20]="", decimal[20]="";
int cont_entero=0, cont_decimal=0;

//separar las cadenas la parte entera y la decimal
//se valida que si no tiene punto lo coloque al final
if (punto==-1)
punto=strlen(c);

for (int i=0;i<strlen(c);i++){
if (i<punto){
entera[cont_entero]=c[i];
cont_entero++;
}
else{
if (i>punto){
decimal[cont_decimal]=c[i];
cont_decimal++;
}
}
}
//se finalizan las cadenas
entera[cont_entero]='';
decimal[cont_decimal]='';

//hacer los calculos para pasar cada parte a numeros
int potencia_entero, potencia_decimal, divisor;
float nro_entero=0, nro_decimal=0;

potencia_entero=strlen(entera)-1;
potencia_decimal=strlen(decimal)-1;
divisor=potencia(10,strlen(decimal));

for (int i=0;i<strlen(entera);i++){
switch(entera[i]){
case '0': nro_entero += 0*potencia(10,potencia_entero);break;
case '1': nro_entero += 1*potencia(10,potencia_entero);break;
case '2': nro_entero += 2*potencia(10,potencia_entero);break;
case '3': nro_entero += 3*potencia(10,potencia_entero);break;
case '4': nro_entero += 4*potencia(10,potencia_entero);break;
case '5': nro_entero += 5*potencia(10,potencia_entero);break;
case '6': nro_entero += 6*potencia(10,potencia_entero);break;
case '7': nro_entero += 7*potencia(10,potencia_entero);break;
case '8': nro_entero += 8*potencia(10,potencia_entero);break;
case '9': nro_entero += 9*potencia(10,potencia_entero);break;
}
potencia_entero--;
}

for (int i=0;i<strlen(decimal);i++){
switch(decimal[i]){
case '0': nro_decimal += 0*potencia(10,potencia_decimal);break;
case '1': nro_decimal += 1*potencia(10,potencia_decimal);break;
case '2': nro_decimal += 2*potencia(10,potencia_decimal);break;
case '3': nro_decimal += 3*potencia(10,potencia_decimal);break;
case '4': nro_decimal += 4*potencia(10,potencia_decimal);break;
case '5': nro_decimal += 5*potencia(10,potencia_decimal);break;
case '6': nro_decimal += 6*potencia(10,potencia_decimal);break;
case '7': nro_decimal += 7*potencia(10,potencia_decimal);break;
case '8': nro_decimal += 8*potencia(10,potencia_decimal);break;
case '9': nro_decimal += 9*potencia(10,potencia_decimal);break;
}
potencia_decimal--;
}

nro_decimal/=divisor;
n=nro_entero+nro_decimal;
return;
}


//----------------------------------------------------------------------
//FUNCION PARA OBTENER EL NRO DE NOTAS
void obtener_ponderados(char l[], char ponderados[]){

int contador=0;
int pos=0;
int primer_tabulador=0;

strcpy(ponderados,'');
for (int i=0;i<=strlen(l);i++){
if (l[i]=='t')
contador++;
if (contador>=2){
if (primer_tabulador==0){
primer_tabulador++;
}
else{
ponderados[pos]=l[i];
pos++;
}
}
}
ponderados[pos]='';

return;
}



//----------------------------------------------------------------------
//FUNCION QUE DIVIDE LA LINEA LEIDA DEL ARCHIVO EN DATOS VALIDOS
void obtener_datos_alumno(char l[], reg_alumno &e){

char c[255]="";
int pos=0;
int conta=0;

for (int i=0;i<strlen(l);i++){
if (l[i]!='t'){
c[pos]=l[i];
pos++;
}
else{
conta++;
switch(conta){
case 1:
c[pos]='';
strcpy(e.documento,c);
strcpy(c,'');
pos=0;
break;
case 2:
c[pos]='';
strcpy(e.nombre,c);
strcpy(c,'');
pos=0;
break;
default:
c[pos]='t';
pos++;

}
}
}
c[pos]='';
strcpy(e.notas,c);
return;
}


//----------------------------------------------------------------------
//FUNCION PARA CALCULAR EL PROMEDIO DE UN ESTUDIANTE
float calcular_promedio_est(char ponderados[], char notas[]){

char c[10]="";
int pos=0;
int nro_calif=0;
int nro_ponde=0;
float calif[15];
float ponde[15];

//colocamos los ponderados en un vector pero como valores no como cadenas

for (int i=0;i<strlen(ponderados);i++){
if (ponderados[i]!='t'){
c[pos]=ponderados[i];
pos++;
}
else{
c[pos]='';
cadafloat(ponde[nro_ponde],c);
nro_ponde++;
pos=0;
strcpy(c,"");
}
}
c[pos]='';
cadafloat(ponde[nro_ponde],c);
nro_ponde++;
pos=0;
strcpy(c,"");

//se hace lo mismo con las notas
strcpy(c,"");
for (int i=0;i<strlen(notas);i++){
if (notas[i]!='t'){
c[pos]=notas[i];
pos++;
}
else{
c[pos]='';
cadafloat(calif[nro_calif],c);
nro_calif++;
pos=0;
strcpy(c,"");
}
}
c[pos]='';
cadafloat(calif[nro_calif],c);
nro_calif++;
pos=0;
strcpy(c,"");

//se verifica que el n£mero de porcentajes y el numero de calificaciones
//sean inguales en caso de nos serlo se toma el menor de los dos

int nro_notas=0;
if (nro_ponde>nro_calif){
nro_notas=nro_calif;
}
else{
nro_notas=nro_ponde;
}

float promedio=0;

for (int i=0;i<nro_notas;i++){
promedio+=ponde[i]*calif[i];
}

return promedio;

}


//----------------------------------------------------------------------
//FUNCION PARA CARGAR CURSO DESDE UN ARCHIVO PLANO
void leer_archivo_plano(int &nro_cursos, int &nro_estudiantes){
char curso[15], ruta[100];

//borra pantalla y pide nombre de curso y ruta de archivo
clrscr();
gotoxy(15,10);
cout << "Escriba el nombre del curso: ";
cin >> curso;
gotoxy(15,12);
cout << "Escriba la ruta del archivo: ";
cin >> ruta;
//arma la cadena completa con ruta y nombre
strcat(ruta,curso);

//abrir el archivo de texto
ifstream entrada(ruta);
if (!entrada){ //si no es posible abrirlo se informa de ello y se retorna a la funcion principal
clrscr();
gotoxy(10,14);
cout << "No puede abrir el archivo: -" << ruta << "- intente nuevamente...";
getch();//linea para que se detenga y muestre el mensaje
return;
}
//si se llega hasta aqui es que fue posible abrir el archivo
//entonces se debe cargar
char linea[255];//lee el archivo linea por linea
int contador=0;//para saber cuantas lineas se van leyendo
char ponderados[100]; //almacena los encabezados de los % de cada nota en una cadena

float promedio_curso=0, suma_promedios=0;
int nro_est_curso=0;

nro_cursos++;
while(entrada){
entrada.getline(linea,sizeof(linea));//lee la linea desde el archivo
if (contador==0)//la primera vez que entra averigue cuantas notas vienen
obtener_ponderados(linea,ponderados);//para la primera linea toma solo la parte de los % de las notas
else{
nro_estudiantes++;
obtener_datos_alumno(linea, ::estudiantes[nro_estudiantes]);//para las siguientes lineas toma los datos del estudiante y los asigna en la variable "a" del tipo estructura reg_alumno
strcpy(::estudiantes[nro_estudiantes].nombre_curso,curso);//asigna el curso en el que vamos
::estudiantes[nro_estudiantes].promedio=calcular_promedio_est(ponderados,::estudiantes[nro_estudiantes].notas);//calcula el promedio
suma_promedios+=::estudiantes[nro_estudiantes].promedio;//va sumando los promedios de cada estudiante
nro_est_curso++;
}
contador++;
}
//calcula el promedio del curso
promedio_curso=suma_promedios/nro_est_curso;

//asigna los valore del curso
strcpy(::cursos[nro_cursos].nombre_curso,curso);
::cursos[nro_cursos].promedio_curso=promedio_curso;

entrada.close();
clrscr();
gotoxy(10,5); cout << "ARCHIVO " << curso << " CARGADO...";
getch();
return;
}

//---------------------------------------------------------------------
//FUNCION PARA LISTAR CURSOS CARGADOS
void listar_cursos(int nro_cursos){

int y=5;
int item=1;

clrscr();
if (nro_cursos==-1){
gotoxy(10,5);
cout << "NO SE HAN CARGADO CURSOS...";
}
else{

//colocar los encabezados
gotoxy(10,y); cout << "ITEM";
gotoxy(20,y); cout << "NOMBRE CURSO";
gotoxy(34,y); cout << "PROMEDIO";
y++;
//colocar los datos del vector de cursos
for (int i=0;i<=nro_cursos;i++){
y+=1;
gotoxy(10,y); cout << item;
gotoxy(20,y); cout << ::cursos[i].nombre_curso;
gotoxy(34,y); cout << ::cursos[i].promedio_curso;
if (y==20){
getch();
clrscr();
y=5;
gotoxy(10,y); cout << "ID CURSO";
gotoxy(20,y); cout << "NOMBRE CURSO";
gotoxy(34,y); cout << "PROMEDIO";
y++;
}
item++;
}
}
getch();
}

//----------------------------------------------------------------------
//FUNCION PARA LISTAR LOS ESTUDIANTES DE UN CURSO
void listar_estudiantes(int nro_cursos, int nro_estudiantes){

//valida si hay cursos cargados
clrscr();
if (nro_cursos==-1){
gotoxy(10,5);
cout << "NO SE HAN CARGADO CURSOS...";
getch();
return;
}

char curso[15];
int existe_curso=-1;

//borra pantalla y pide nombre de curso
clrscr();
gotoxy(15,10);
cout << "Escriba el nombre del curso: ";
cin >> curso;

//leido el curso se busca en el vector de cursos si existe
for (int i=0;i<=nro_cursos;i++){
if (strcmp(::cursos[i].nombre_curso,curso)==0){
existe_curso=0;
break;
}
}

int y=5;

if (existe_curso==-1){
clrscr();
gotoxy(10,5); cout << "NO SE ENCUENTA UN CURSO CON ESE NOMBRE...";
}
else{
//colocar los encabezados
clrscr();
gotoxy(10,y); cout << "DOCUMENTO";
gotoxy(27,y); cout << "NOMBRE ESTUDIANTE";
gotoxy(70,y); cout << "PROMEDIO";
y++;
//colocar los datos del vector de cursos
for (int i=0;i<nro_estudiantes;i++){
if (strcmp(::estudiantes[i].nombre_curso,curso)==0){
y+=1;
gotoxy(10,y); cout << ::estudiantes[i].documento;
gotoxy(27,y); cout << ::estudiantes[i].nombre;
gotoxy(70,y); cout << ::estudiantes[i].promedio;
if (y==20){
getch();
clrscr();
y=5;
gotoxy(10,y); cout << "DOCUMENTO";
gotoxy(27,y); cout << "NOMBRE ESTUDIANTE";
gotoxy(70,y); cout << "PROMEDIO";
y++;
}
}
}
}
getch();
}


//----------------------------------------------------------------------
//FUNCION QUE ORDENA Y MUESTRA EL TOP 10 DE LOS MEJORES ESTUDIANTES

void top10(int nro_cursos, int nro_estudiantes, reg_alumno a[]){
//valida si hay cursos cargados
clrscr();
if (nro_cursos==-1){
gotoxy(10,5);
cout << "NO SE HAN CARGADO CURSOS...";
getch();
return;
}

//como hay cursos cargados entonces se ordenan los estudiantes
//y se muestran los primeros 10

reg_alumno t; //se usara como temporal para el ordenamiento metodo burbuja el menos eficiente pero el mas conocido y facil de entender
float mayor;

for (int i=0;i<nro_estudiantes;i++){
mayor=a[i].promedio;
for (int j=i+1;j<=nro_estudiantes;j++){
if (a[j].promedio>mayor){
//asignar el nuevo mayor
mayor=a[j].promedio;
//asignar a la estructura temporal
strcpy(t.nombre_curso,a[i].nombre_curso);
strcpy(t.documento,a[i].documento);
strcpy(t.nombre,a[i].nombre);
strcpy(t.notas,a[i].notas);
t.promedio=a[i].promedio;
//asignar el mayor a la posicion nueva
strcpy(a[i].nombre_curso,a[j].nombre_curso);
strcpy(a[i].documento,a[j].documento);
strcpy(a[i].nombre,a[j].nombre);
strcpy(a[i].notas,a[j].notas);
a[i].promedio=a[j].promedio;
//asignar el temporal a la posicion que ocupaba el mayor
strcpy(a[j].nombre_curso,t.nombre_curso);
strcpy(a[j].documento,t.documento);
strcpy(a[j].nombre,t.nombre);
strcpy(a[j].notas,t.notas);
a[j].promedio=t.promedio;
}
}
}
//ya ordenado el vector a se muestran los 10 primeros
//colocar los encabezados
int limite=10;
int y=5;

clrscr();
gotoxy(3,y); cout << "#";
gotoxy(6,y); cout << "DOCUMENTO";
gotoxy(22,y); cout << "NOMBRE ESTUDIANTE";
gotoxy(65,y); cout << "PROMEDIO";
gotoxy(74,y); cout << "CURSO";
y++;
//colocar los datos del vector de cursos
if (nro_estudiantes<limite)
limite=nro_estudiantes;

for (int i=0;i<limite;i++){
y+=1;
gotoxy(3,y); cout << i+1;
gotoxy(6,y); cout << a[i].documento;
gotoxy(22,y); cout << a[i].nombre;
gotoxy(65,y); cout << a[i].promedio;
gotoxy(74,y); cout << a[i].nombre_curso;
if (y==20){
getch();
clrscr();
y=5;
gotoxy(3,y); cout << "#";
gotoxy(6,y); cout << "DOCUMENTO";
gotoxy(22,y); cout << "NOMBRE ESTUDIANTE";
gotoxy(65,y); cout << "PROMEDIO";
gotoxy(74,y); cout << "CURSO";
y++;
}
}
getch();
}


//----------------------------------------------------------------------
//FUNCION PARA GUARDAR EN ARCHIVOS BINARIOS
void guardar_binario(int nro_cursos, int nro_estudiantes, reg_curso c[], reg_alumno a[]){

//primero guardar el archivo de cursos

//abrir el archivo binario
ofstream salida_cursos("c:cursos.dat", ios::binary);
//verifica si se pudo abrir el archivo
if (!salida_cursos){
clrscr();
gotoxy(10,5); cout << "NO ES POSIBLE ABRIR EL ARCHIVO";
return;
}

//si lo pudo abrir recorre el vector escribiendo la estructura en el archivo
for (int i=0;i<nro_cursos;i++){
salida_cursos.write((unsigned char *) &c[i], sizeof(c[i]));
}
//cerramos el archivo
salida_cursos.close();


//guardar el archivo de estudiantes

//abrir el archivo binario
ofstream salida_estudiantes("c:estudiantes.dat", ios::binary);
//verifica si se pudo abrir el archivo
if (!salida_estudiantes){
clrscr();
gotoxy(10,5); cout << "NO ES POSIBLE ABRIR EL ARCHIVO";
return;
}

//si lo pudo abrir recorre el vector escribiendo la estructura en el archivo
for (int i=0;i<nro_estudiantes;i++){
salida_estudiantes.write((unsigned char *) &a[i], sizeof(a[i]));
}
//cerramos el archivo
salida_estudiantes.close();


clrscr();
gotoxy(10,5); cout << "ARCHIVO BINARIO GENERADO...";
getch();
}



//----------------------------------------------------------------------
//FUNCION PARA CARGAR DESDE ARCHIVOS BINARIOS
void cargar_binario(int &nro_cursos, int &nro_estudiantes){



//leer primero el archivo de cursos
nro_cursos=-1;
ifstream entrada_cursos("c:cursos.dat", ios::binary);
//se verifica si se puede abrir el archivo
if (!entrada_cursos){
clrscr();
gotoxy(10,5); cout << "NO ES POSIBLE ABRIR EL ARCHIVO";
return;
}
while(!entrada_cursos.eof()){
nro_cursos++;
entrada_cursos.read((unsigned char *) &cursos[nro_cursos], sizeof(cursos[nro_cursos]));
}
entrada_cursos.close();

//leer el archivo de estudiantes
nro_estudiantes=-1;
ifstream entrada_estudiantes("c:estudiantes.dat", ios::binary);
//se verifica si se puede abrir el archivo
if (!entrada_estudiantes){
clrscr();
gotoxy(10,5); cout << "NO ES POSIBLE ABRIR EL ARCHIVO";
return;
}
while(!entrada_estudiantes.eof()){
nro_estudiantes++;
entrada_estudiantes.read((unsigned char *) &estudiantes[nro_estudiantes], sizeof(estudiantes[nro_estudiantes]));
}
entrada_estudiantes.close();

clrscr();
gotoxy(10,5); cout << "ARCHIVO BINARIO CARGADO...";
getch();

}



//----------------------------------------------------------------------
//LA FUNCION PRINCIPAL
void main(void){

int nro_cursos=-1, nro_estudiantes=-1;
char opcion;

do{
opcion=menu();

switch(opcion){
case '1': leer_archivo_plano(nro_cursos,nro_estudiantes); break;
case '2': listar_cursos(nro_cursos); break;
case '3': listar_estudiantes(nro_cursos,nro_estudiantes); break;
case '5': top10(nro_cursos,nro_estudiantes,estudiantes); break;
case '6': guardar_binario(nro_cursos,nro_estudiantes,cursos,estudiantes); break;
case '7': cargar_binario(nro_cursos,nro_estudiantes); break;
}

}while (opcion!='0');

}



el archivo que tiene que recivir es el siguiente.

Documento Nombre 0.25 0.2 0.25 0.3
80758890 ACEVEDO CABALLERO ALEJANDRO 5 0.8 0.3 2.4
86090156782 ALVAREZ MAX SERGIO ANDRES 2.3 3.8 1.3 2.5
85080234592 ARANGO NADER NATALIA 2.2 4.3 0.8 0.8
10952917 ARROYO BENAVIDES CARLOS MARIO 0.3 1.2 3.8 1.8
53065620 BADILLO DURAN DIANA CAROLINA 1.3 2.4 4.3 4.8
80795022 BOTERO HERNAN DAVID FERNANDO 0.8 2.5 1.2 3.2

este archivo tiene que ser guardado en txt
porfavor si alguien encuentra el problema se los agradezco