Autor
|
Tema: Error al guardar muchos datos en arrays multidimensional (lenguaje C) (Leído 2,732 veces)
|
alejandrodiaz
Desconectado
Mensajes: 12
|
Buenas, estoy aprendiendo a programar en C y tengo muchas dudas con respecto a guardar datos en los arreglos multidimensionales. // Tengo un ejercicio que dice: Un instituto desea controlar los resultados de los alumnos en las diferentes asignaturas de sus cursos de informatica, el programa debe leer las calificaciones obtenidas en las diferentes asignaturas y visualizar en pantalla el numero de cada estudiante seguipo por la media del estudiantes y una lista de las calificaiones parciales de ese estudiante. el programa visualizará tambien la calificacion media de todos los estudiantes en cada asignatura. // Es la primera vez que hago un ejercicio como este, siempre he hecho cosas sencillas, el caso es que mi codigo va bien hasta el punto en que tengo que guardar las notas en los arrays, ya que en el modo en que lo hago se me sobreescribe las notas de un alumno sobre otra. Para el instituto que lo hago no es por semestres sino por trimestres, tres trimestres en un año. Al final me da datos erroneos, de otras partes de la memoria. Se que deberia usar punteros y funciones pero como dije soy novato y me confundo. Quiero ver primero que funciona y luego darle orden. como seria la forma correcta de guardar las notas para cada alumno y materia? este es mi codigo #include <stdio.h> #include <stdlib.h> #include <string.h> #include <conio.h> //Declarando variables globales para que el usuario establezca limites en los ciclos FOR// int cant_alum; int cant_mate; int cant_nota; int main() { //Arrays para nombres de alumnos y materias ---Arrays de caracteres---// char nom_alum[cant_alum][30]; char nom_mate[cant_mate][40]; //Arrays para notas de trayectos ---not_tra1 = notas del trayecto1--- // int not_tra1[4][cant_nota]; int not_tra2[4][cant_nota]; int not_tra3[4][cant_nota]; //Llamando a las variables globales// cant_alum; cant_mate; cant_nota; //Enteros usados en los ciclos FOR// int i; int j; int k; //Inicia el programa// printf("Cuantos alumnos desea registrar?: "); for (i=1; i<cant_alum+1; i++){ } printf("\nCuantas materias desea registrar?: "); for(i=1; i<cant_alum+1; i++){ } printf("\nCuantas evaluaciones fueron por trayecto?: "); //PARTE 2: GUARDAR DATOS. MAL HECHO// for(i=1; i<cant_alum+1; i++){ printf("\n\n********** Alumno nro %d : %s **********\n" , i , nom_alum [i ]); for(j=1; j<cant_mate+1; j++){ printf("\n\nIngrese las notas parciales de %s\n", nom_mate [j ]); printf("\n===== Trayecto 1 =====\n\n"); for (k=1; k<cant_nota+1; k++){ scanf("%d",¬_tra1 [k ]); } printf("\n===== Trayecto 2 =====\n\n"); for (k=1; k<cant_nota+1; k++){ scanf("%d",¬_tra2 [k ]); } printf("\n===== Trayecto 3 =====\n\n"); for (k=1; k<cant_nota+1; k++){ scanf("%d",¬_tra3 [k ]); } } } printf("Esto se muestra sin error"); //Aca si aplico ciclos FOR con printf para mostrar los valores guardados en los arreglos, todos los datos mostrados son erroneos// return 0; }
Al analizar pienso que guardar las notas de la forma ejemplo: scanf("%d", ¬_tra1 [k]); no está bien hecho, creo que deberia ser ¬_tra1 - ... donde "X" sea la variable pero no se como organizarlo, de las maneras que las he hecho todas malas.
tambien para los arreglos de trayectos tengo not_tra1[4][cant_nota]; Donde 4 quise definir la cantidad de trayectos pero se ahora se que es un error porque no dejo crecer la matriz en filas, quisiera que sea automatica pero dejando [ ] vacio me tira error. Y por ultimo veo que guardar todas las notas de los mismos alumnos y materias de un trayecto en un solo arreglo es una cantidad de numeros desorganizada.. pero con tanto lio no se como avanzar Espero me puedan ayudar, soy muy novato como ven... Gracias!
|
|
|
En línea
|
|
|
|
joecarl
Desconectado
Mensajes: 24
|
Esta parte del código está mal: //Arrays para nombres de alumnos y materias ---Arrays de caracteres---// char nom_alum[cant_alum][30]; char nom_mate[cant_mate][40]; //Arrays para notas de trayectos ---not_tra1 = notas del trayecto1--- // int not_tra1[4][cant_nota]; int not_tra2[4][cant_nota]; int not_tra3[4][cant_nota]; //Llamando a las variables globales// cant_alum; cant_mate; cant_nota;
No puedes definir el tamaño de un array con una variable, es decir: char nom_alum[cant_alum][30]; char nom_mate[cant_mate][40]; int not_tra1[4][cant_nota];
Deberia ser: char nom_alum[10][30]; char nom_mate[10][40]; int not_tra1[4][10];
He puesto 10, pero eso no quiere decir que haya q usar las 10, sino que como maximo tenemos 10. Otra cosa es que si ya estas creando varios arrays para cada trayecto entonces el [4] sobra, aunque quedaria más organizado en un solo array, es decir, en lugar de: int not_tra1[4][cant_nota]; int not_tra2[4][cant_nota]; int not_tra3[4][cant_nota];
Deberías poner: int not_tra[4][10];
Luego esta parte: //Llamando a las variables globales// cant_alum; cant_mate; cant_nota;
No sirve para nada, no tiene efecto, esas lineas las puedes eliminar directamente. Cuando entiendas eso respónde al post y seguimos.
|
|
« Última modificación: 30 Julio 2015, 11:33 am por joecarl »
|
En línea
|
|
|
|
alejandrodiaz
Desconectado
Mensajes: 12
|
Perfecto, ya he modificado el arreglo de trayecto, y los char lo he puesto. voy a seguir con los valores de tu ejemplo y luego los modifico a los que requiera. char nom_alum[10][30]; char nom_mate[10][40]; int not_tra[4][10];
habia puesto 4 porque en los FOR iniciaba con el i=1, para en el printf usar el "i" para ordenar los mensajes por el numero de alumnos ejemplo: alumno nro 1; igual veo que es un desperdicio de elemento. También quite las variables globales del main.. estaba apenas aprendiendo la diferencia entre variables locales y globales. Gracias por la aclaratoria.
|
|
« Última modificación: 30 Julio 2015, 11:45 am por alejandrodiaz »
|
En línea
|
|
|
|
joecarl
Desconectado
Mensajes: 24
|
Perfecto, seguimos: fflush(stdin);
Esto tampoco tiene efecto, fflush sirve para vaciar los buffer de salida, los de entrada no puedes vaciarlos de esta manera. Asique elimina también estas líneas. Si solo quieres 3 trayectos pues declara solo 3: int not_tra[3][10];
Y el primer trayecto sera el 0 el segundo el 1 y el tercero el 2. Acostumbrate a reccorrer los arrays de esa manera, así es como se debe hacer siempre en C. Con respecto a esto: for(j=1; j<cant_mate+1; j++){ printf("\n\nIngrese las notas parciales de %s\n", nom_mate[j]); printf("\n===== Trayecto 1 =====\n\n"); for (k=1; k<cant_nota+1; k++){ printf("Nota %d: ", k); fflush(stdin); scanf("%d",¬_tra1[k]); } printf("\n===== Trayecto 2 =====\n\n"); for (k=1; k<cant_nota+1; k++){ printf("Nota %d: ", k); fflush(stdin); scanf("%d",¬_tra2[k]); } printf("\n===== Trayecto 3 =====\n\n"); for (k=1; k<cant_nota+1; k++){ printf("Nota %d: ", k); fflush(stdin); scanf("%d",¬_tra3[k]); } } }
Lo puedes sustituir por: int tra;//variable contadora para el bucle de trayectos, la puedes declarar en otro sitio si quieres. for(j=1; j<cant_mate+1; j++){ printf("\n\nIngrese las notas parciales de %s\n", nom_mate[j]); for(tra=0; tra<3; tra++){ printf("\n===== Trayecto %d =====\n\n",tra+1); for (k=0; k<cant_nota; k++){ printf("Nota %d: ", k+1); scanf("%d",¬_tra[tra][k]); } } }
Fijate en como cambia la forma de recorrer el array: for (k=1; k<cant_nota+1; k++) //mal for (k=0; k<cant_nota; k++) //bien
|
|
« Última modificación: 30 Julio 2015, 12:48 pm por joecarl »
|
En línea
|
|
|
|
alejandrodiaz
Desconectado
Mensajes: 12
|
Buenisimo, ya voy entendiendo amigo. Lo de fflush(stdin) lo habia puesto porque al principio tengo un scanf y luego le sigue un gets, entonces al compilar me saltaba un ciclo en for, lei algo sobre que el scanf al finalizar agrega un salto de line \n y el gets lo leia y guardaba el espacio en un elemento del arreglo. printf("Cuantos alumnos desea registrar?: "); scanf("%d", &cant_alum ); // <=== aca tengo el scanf// for (i=1; i<cant_alum+1; i++){ printf("Alumno nro %d: ",i ); //<===y aqui al compilar en vez de "Alumno nro 1, me saltaba a Alumno nro 2"// gets(nom_alum [i ]); //<=== este el gets//
Ya empiezo a corregir el resto. Con esto podré ya imprimir todos los datos agregados o todavia falta?
|
|
|
En línea
|
|
|
|
joecarl
Desconectado
Mensajes: 24
|
Sí lo del retorno del línea es cierto, pero es que fflush(stdin); no deberia solucionarlo. ¿A ti te funciona? Porque eso es muy raro que funcione, pero bueno si te va bien así déjalo, aunque ya te digo que a mi eso nunca me ha funcionado, la solucion correcta es otra más compleja, si quieres más adelante te la explico.
Y sí, yo creo que con eso ya estaría todo arreglado, si no te funciona y no encuentras el error pues coméntalo.
|
|
|
En línea
|
|
|
|
alejandrodiaz
Desconectado
Mensajes: 12
|
Si bueno, en ese caso que mencione me funciono y no molesto mas, por eso lo puse en todos lados para prevenir.
Cuando tengas oportunidad explicas la solucion para no usar fflush(stdin) todo lo que ayude en mi aprendizaje es bienvenido.
Y claro seguro seguire comentando, me toca aplicar funciones, punteros y sacar los promedios, estoy casi seguro que tendre muchos errores.
Muchas gracias amigo por la ayuda, seguire editando el codigo.
|
|
|
En línea
|
|
|
|
joecarl
Desconectado
Mensajes: 24
|
La forma adecuada de leer enteros por teclado sin dar pie a problemas es así: int num; char buffer[100];//cadena de texto auxiliar para copiar el buffer de entrada //------ fgets(buffer,100,stdin); //copiamos el buffer de entrada a la cadena auxiliar sscanf(buffer, "%d", &num); //leemos el entero de la cadena auxiliar
Esto se hace precisamente para quitar ese retorno de linea que nos está haciendo la puñeta, ya que con fgets estamos vaciando stdin por completo. EDIT: también puedes meter ese código en una función para no tener que andar repitiéndolo todo el rato: int leerEntero(){ int num; char buffer[100];//cadena de texto auxiliar para copiar el buffer de entrada fgets(buffer,100,stdin); //copiamos el buffer de entrada a la cadena auxiliar sscanf(buffer, "%d", &num); //leemos el entero de la cadena auxiliar return num; }
También añado que leer una cadena de texto con gets es inseguro ya que gets no controla el numero máximo de caracteres que vas a leer, por tanto deberías usar fgets también. Es decir, en lugar de: gets(nom_alum[i]);
Usa: fgets(nom_alum[i],30,stdin);
Por ultimo, decirte que he puesto 30 pero lo correcto es usar un DEFINE arriba del todo para no tener que andar poniendo 30 por todas partes, es decir: #define MAX_CHARS 30 //esto arriba del todo int main(...){ //..... char nom_alum[10][MAX_CHARS]; //.....otras declaraciones.... //.....hacer tareas..... fgets(nom_alum[i], MAX_CHARS,stdin); //..... }
|
|
« Última modificación: 30 Julio 2015, 21:07 pm por joecarl »
|
En línea
|
|
|
|
|
Mensajes similares |
|
Asunto |
Iniciado por |
Respuestas |
Vistas |
Último mensaje |
|
|
[Solucionado] Error al guardar datos binarios
Programación Visual Basic
|
Sancho.Mazorka
|
3
|
2,826
|
26 Octubre 2010, 04:12 am
por Sancho.Mazorka
|
|
|
Access 2007 y visual basic 2008, error ar guardar lo datos
Dudas Generales
|
01munrra
|
2
|
4,906
|
11 Febrero 2012, 20:49 pm
por 01munrra
|
|
|
Error al guardar datos en MySQL con PHP :(
PHP
|
JonaLamper
|
1
|
2,173
|
5 Diciembre 2015, 21:51 pm
por sebasgb
|
|
|
Error al devolver array multidimensional
Java
|
viher
|
0
|
1,863
|
25 Diciembre 2014, 00:30 am
por viher
|
|
|
Guardar muchos datos en una sola linea de un txt para su lectura
.NET (C#, VB.NET, ASP)
|
cael1011
|
2
|
2,087
|
1 Octubre 2016, 00:51 am
por cael1011
|
|