When Im in interfaz_test() and call fgets or fscanf I get a Segmentation Fault, but can´t see why. Any help would be appreciated. Thanks.
/* Proyecto1.c
*
* P r o g r a m a q u e c a l i f i c a
* u n t e s t a r b i t r a r i o y
* m u e s t r a r e s u l t a d o s
*/
#define _GNU_SOURCE
#include <stdio.h>
#include <stdlib.h>
#include <math.h>
#include <errno.h>
#include <string.h>
#include <ctype.h>
#include "prototipos.h"
int main(int argc, char **argv)
{
/* variables de control */
int j=1, i=0, help_int, sistemas_ctrl=0, estudiantes_ctrl=0;
char *decision, *sistemas, *cantidad_estudiantes;
/* asignación dinámica (pudo usarse arreglos ya que es una cantidad fija de bytes) */
if (((sistemas = (char *)calloc(20, sizeof(char))) == NULL) || ((cantidad_estudiantes = (char *)calloc(2, sizeof(char))) == NULL) || ((decision=(char *)malloc(sizeof(char)*2)) == NULL)) {
fprintf(stderr, "Insuficiente espacio en memoria principal!\n");
exit(EXIT_SUCCESS);
}
/* en caso de --help a main */
if (argc > 1) {
help_int = help(*(argv+1));
if (help_int)
exit(EXIT_SUCCESS);
}
/* detección de errores en los argumentos a main */
if (argc != 1) {
if (argc == 2) {
if (!(validacion(*(argv+1))))
fprintf(stderr, "\n\t****** Argumento número de sistemas inválido, el programa lo ignorará ******\n");
else
sistemas_ctrl=1;
}
else if (argc == 3) {
if (!(validacion(*(argv+1))))
fprintf(stderr, "\n\t****** Argumento número de sistemas inválido, el programa lo ignorará ******\n");
else
sistemas_ctrl=1;
if (!(validacion(*(argv+2))))
fprintf(stderr, "\n\t****** Argumento número de estudiantes inválido, el programa lo ignorará ******\n");
else
estudiantes_ctrl=1;
}
else
fprintf(stderr, "\n\t****** Número de argumentos inválido, el programa tendrá en cuenta los dos primeros ******\n");
}
/* validacion enteros */
if (!sistemas_ctrl || (!(validacion(*(argv+1))))) {
do {
fprintf(stdout, "Proporcione la cantidad de sistemas de calificación: \n-> ");
scanf("%20s", sistemas);
} while (!(sistemas_integer=validacion(sistemas)));
}
else
sistemas_integer = atoi(*(argv+1));
/* arreglo de enteros para cantidad de estudiantes en cada sistema */
cantidad_int = (int *)calloc(sistemas_integer, sizeof(int));
/* mientras haya sistemas */
while (sistemas_integer) {
if (!estudiantes_ctrl || (!(validacion(*(argv+1))))) {
do {
fprintf(stdout, "Escriba la cantidad de estudiantes del sistema %d \n-> ", j);
scanf("%2s", cantidad_estudiantes);
} while (!(*(cantidad_int+i) = validacion(cantidad_estudiantes)));
}
else
*(cantidad_int+i) = atoi(*(argv+2));
/* llamada a la interfaz con los usuarios */
interfaz_test();
/* control */
sistemas_integer--;
i++;
j++;
}
/* escritura en archivo, poco elegante con sistemas_integer... :( */
sistemas_integer=i;
escribir_archivo();
/* calificar */
calificar();
/* el usuario decide qué hacer */
do {
decision = menu(decision);
if (*decision == '1')
individual();
else if (*decision == '2')
colectivo();
else if (*decision == '3')
desviacion();
else
media();
} while(*decision != '5');
exit(EXIT_SUCCESS);
}
/* recibe e imprime los resultados del estudiante de individual() */
void especifico(int sistema, int estudiante)
{
/* control */
int j;
/* apuntador local de la funcion, apunta al sistema */
ptr_estudiantes ptr_local = *ptr_apuntadores;
ptr_local = ptr_local+sistema;
/* apunta al estudiante */
for (j=0; j<estudiante; j++) {
ptr_local = ptr_local->siguiente;
}
for (j=0; j<estudiante; j++) {
printf("\n\nNombre: %s\n\tCódigo: %s\n\tRespuestas: %s\n\tCorrectas: ", ptr_local->nombre, ptr_local->codigo, ptr_local->respuestas);
printf("%d\n\tIncorrectas: %d\n\tNota: %lf\n\n", ptr_local->correctas, ptr_local->incorrectas, (ptr_local->correctas - (ptr_local->incorrectas * 0.5)));
}
}
/* asigna nota a cada estudiante */
void calificar()
{
/* apuntador local de la funcion */
ptr_estudiantes ptr_local = *ptr_apuntadores;
/* control */
int j, i;
for (j=0; j<sistemas_integer; j++)
ptr_local = ptr_local+j;
for (i=0; i<*(cantidad_int+j); i++) {
ptr_local->nota = ptr_local->correctas - (ptr_local->incorrectas * 0.5);
ptr_local = ptr_local->siguiente;
}
}
/* interfaz con el usuario */
char *menu(char *decis)
{
printf("\n\n\tEl examen ha terminado. Escoja una opción:\n\n1. Ver resultado individual.\n2. Ver resultado colectivo.");
printf("\n3. Ver desviación estándar del grupo.\n4. Ver media del grupo.\n5. Salir\n\n-> ");
scanf("%1s", decis);
while (*decis != '1' && *decis != '2' && *decis != '3' && *decis != '4' && *decis != '5') {
printf("\n\n\tArgumento inválido. Escoja una opción:\n\n1. Ver resultado individual.\n2. Ver resultado colectivo.");
printf("\n3. Ver desviación estándar del grupo.\n4. Ver media del grupo.\n5. Salir\n\n-> ");
scanf("%1s", decis);
}
return decis;
}
/* halla la media de la suma de todos los estudiantes */
int media()
{
/* apuntador local de la funcion */
ptr_estudiantes ptr_local = *ptr_apuntadores;
/* control */
int j, i;
/* media aritm tica */
int media=0;
for (j=0; j<sistemas_integer; j++)
ptr_local = ptr_local+j;
for (i=0; i<*(cantidad_int+i); i++) {
media+=ptr_local->nota;
ptr_local = ptr_local->siguiente;
}
return media;
}
/* imprime los resultados de todos los estudiantes */
void colectivo()
{
/* apuntador local de la funcion */
ptr_estudiantes ptr_local = *ptr_apuntadores;
/* variables de control */
int j, i;
for (j=0; j<sistemas_integer; j++)
ptr_local = ptr_local+j;
for (i=0; i<*(cantidad_int+j); i++) {
printf("************************\nNombre\tCódigo\tRespuestas\tCorrectas\tIncorrectas\tNota\n\n");
printf("%s\t%s\t%s\t", ptr_local->nombre, ptr_local->codigo, ptr_local->respuestas);
printf("%d\t%d\t%lf", ptr_local->correctas, ptr_local->incorrectas, (ptr_local->correctas - (ptr_local->incorrectas * 0.5)));
printf("\n************************");
ptr_local = ptr_local->siguiente;
}
}
/* verifica si se pasó --help como argumento a main*/
int help(char *argumento)
{
char *help = (char *)malloc(sizeof(char)*10);
help = "--help";
/* Si se proporciona --help... */
if (!(strncmp(argumento, help, 6)))
{
fprintf(stdout, "\nUso:\n\t ./Proyecto1 2 4 => El programa asume cantidad de sistemas el argumento 2, cada sistema de 4 estudiantes.\n");
fprintf(stdout, "\tPuede proporcionar un sólo argumento, que sería la cantidad de sistemas, para ser cuestionado durante el programa ");
fprintf(stdout, " sobre la cantidad de estudiantes de cada uno.\n\n");
return 0x1;
}
else
return 0x0;
}
/* imprime la desviaci n est ndar de los resultados */
void desviacion()
{
int *datos;
/* variables de control */
int j, i, util=0;
/* desviacion est ndar */
int desviacion=0;
/* apuntador local de la funcion */
ptr_estudiantes ptr_local = *ptr_apuntadores;
/* escribe en la variable util la cantidad total de estudiantes */
for (j=0; j<sistemas_integer; j++)
for (i=0; i<*(cantidad_int+j); i++) {
util++;
}
datos = calloc(util, sizeof(int));
/* halla la desviacion */
for (j=0; j<sistemas_integer; j++)
ptr_local = ptr_local+j;
for (i=0; i<*(cantidad_int+j); i++) {
desviacion += ptr_local->nota;
ptr_local = ptr_local->siguiente;
}
}
/* escribe en un archivo los resultados */
void escribir_archivo()
{
/* archivo */
FILE *archivio;
/* variables de control */
int j,i;
/* apuntador local de la funcion */
ptr_estudiantes ptr_local = *ptr_apuntadores;
/* copiado a archivo */
if ((archivio = fopen("estudiantes.dat", "w+")) != NULL) {
for (j=0; j<sistemas_integer; j++) {
ptr_local = ptr_local+j;
for (i=0; i<*(cantidad_int+i); i++) {
fwrite(ptr_local, sizeof(Estudiantes), 1, archivio);
ptr_local = ptr_local->siguiente;
}
}
}
/* Si no hay espacio en disco... */
else {
fprintf(stderr, "\n\n***** Insuficiente espacio en disco *****\n\n");
exit(EXIT_SUCCESS);
}
fclose(archivio);
}
/* escoje 1 estudiante y lo env a a especifico() */
void individual()
{
/* apuntador local de la funcion */
ptr_estudiantes ptr_local = *ptr_apuntadores;
/* variables de control */
int j, i, sistema_int, estudiante_int;
char sistema[2];
char estudiante[2];
printf("¿De qué estudiante quiere ver los resultados?\n");
/* despliega las opciones */
for (j=0; j<sistemas_integer; j++)
ptr_local = ptr_local+j;
for (i=0; i<*(cantidad_int+j); i++) {
if (i==0)
printf("Sistema %d\n\n", j+1);
printf("%d %s", i, ptr_local->nombre);
ptr_local = ptr_local->siguiente;
}
do {
printf("Elija sistema y estudiante: \nSistema #\n-> ");
scanf("%2s", sistema);
} while (!(sistema_int = validacion(sistema)));
do {
printf("\nEstudiante #\n-> ");
scanf("%2s", estudiante);
} while (!(estudiante_int = validacion(estudiante)));
/* pasa sistema y estudiante a verle el rendimiento */
especifico(sistema_int, estudiante_int);
}
/* valida enteros */
int validacion (const char * const valor_validar)
{
/* variables locales */
int retorno = atoi(valor_validar);
int a = 0;
int tope = (pow(2, sizeof(int)*8) / 2 - 1);
if (retorno <= 0)
{
fprintf (stderr, "Por favor ingrese un numero entero positivo.\n");
return 0;
}
if (valor_validar[0] == '+')
a = 1;
else
a = 0;
for (a; valor_validar[a] != '\0'; a++)
{
if (!(isdigit(valor_validar[a])))
{
fprintf (stderr, "Por favor ingrese un numero entero positivo.\n");
return 0;
}
}
if (tope == retorno)
{
fprintf(stdout, "Rango por encima del maximo valor permitido, intente de nuevo.\n");
return 0;
}
return retorno;
}
/* interfaz con el usuario */
void interfaz_test()
{
/* variables de control */
int i, j, cuantos;
static int sistema=1, contador=0, k=0;
/* archivo */
FILE *preguntas;
/* apuntador al arreglo de la pregunta, escrito por fread */
char *pregunta;
/* nuevo nodo */
ptr_estudiantes ptr_nuevo=(ptr_estudiantes)calloc(1, sizeof(Estudiantes));
/* apuntador a apuntadores de estructura; cada uno contiene el primer nodo de del sistema */
if (sistema==1)
ptr_apuntadores=(ptr_estudiantes*)calloc(sistemas_integer, sizeof(Estudiantes));
/* se le asigna el nodo ptr_nuevo al apuntador referenciado por contador */
ptr_apuntadores[contador]=ptr_nuevo;
/* ciclo "principal" */
for (i=0; i<*(cantidad_int+k); i++) {
/* asigna memoria para los miembros de la estructura y abre un archivo para actualización */
if ((ptr_nuevo->siguiente=(ptr_estudiantes)malloc(sizeof(Estudiantes))) != NULL || (ptr_nuevo->nombre=(char*)calloc(20, sizeof(char))) != NULL || (ptr_nuevo->codigo=(char*)calloc(5, sizeof(char))) != NULL || (preguntas=fopen("examen", "r")) != NULL) {
printf("Bienvenido al test, estudiante %d, escriba su nombre\n-> ", i+1);
fgets(ptr_nuevo->nombre, 20, stdin);
//fscanf(stdin, "%20s", ptr_nuevo->nombre);
do {
printf("Escriba su código\n-> ");
fscanf(stdin, "%5s", ptr_nuevo->codigo);
} while (!(ptr_nuevo->codigo_int = validacion(ptr_nuevo->codigo)));
/* examen */
cuantos = fscanf(preguntas, "%s");
pregunta = (char *)calloc(cuantos, sizeof(char));
fscanf(preguntas, "%s", pregunta);
scanf("%1s", ptr_nuevo->respuestas+0);
while (ptr_nuevo->respuestas[0] != '0' && ptr_nuevo->respuestas[0] != '1') {
fprintf(stdout, "\n\nRecuerde que sólo se admite 0 para falso y 1 para verdadero\n\n");
scanf("%1s", ptr_nuevo->respuestas+0);
}
scanf("%1s", ptr_nuevo->respuestas+1);
while (ptr_nuevo->respuestas[1] != '0' && ptr_nuevo->respuestas[1] != '1') {
fprintf(stdout, "\n\nRecuerde que sólo se admite 0 para falso y 1 para verdadero\n\n");
scanf("%1s", ptr_nuevo->respuestas+1);
}
scanf("%1s", ptr_nuevo->respuestas+2);
while (ptr_nuevo->respuestas[2] != '0' && ptr_nuevo->respuestas[2] != '1') {
fprintf(stdout, "\n\nRecuerde que sólo se admite 0 para falso y 1 para verdadero\n\n");
scanf("%1s", ptr_nuevo->respuestas+2);
}
scanf("%1s", ptr_nuevo->respuestas+3);
while (ptr_nuevo->respuestas[3] != '0' && ptr_nuevo->respuestas[3] != '1') {
fprintf(stdout, "\n\nRecuerde que sólo se admite 0 para falso y 1 para verdadero\n\n");
scanf("%1s", ptr_nuevo->respuestas+3);
}
scanf("%1s", ptr_nuevo->respuestas+4);
while (ptr_nuevo->respuestas[4] != '0' && ptr_nuevo->respuestas[4] != '1') {
fprintf(stdout, "\n\nRecuerde que sólo se admite 0 para falso y 1 para verdadero\n\n");
scanf("%1s", ptr_nuevo->respuestas+4);
}
scanf("%1s", ptr_nuevo->respuestas+5);
while (ptr_nuevo->respuestas[5] != '0' && ptr_nuevo->respuestas[5] != '1') {
fprintf(stdout, "\n\nRecuerde que sólo se admite 0 para falso y 1 para verdadero\n\n");
scanf("%1s", ptr_nuevo->respuestas+5);
}
scanf("%1s", ptr_nuevo->respuestas+6);
while (ptr_nuevo->respuestas[6] != '0' && ptr_nuevo->respuestas[6] != '1') {
fprintf(stdout, "\n\nRecuerde que sólo se admite 0 para falso y 1 para verdadero\n\n");
scanf("%1s", ptr_nuevo->respuestas+6);
}
scanf("%1s", ptr_nuevo->respuestas+7);
while (ptr_nuevo->respuestas[7] != '0' && ptr_nuevo->respuestas[7] != '1') {
fprintf(stdout, "\n\nRecuerde que sólo se admite 0 para falso y 1 para verdadero\n\n");
scanf("%1s", ptr_nuevo->respuestas+7);
}
scanf("%1s", ptr_nuevo->respuestas+8);
while (ptr_nuevo->respuestas[8] != '0' && ptr_nuevo->respuestas[8] != '1') {
fprintf(stdout, "\n\nRecuerde que sólo se admite 0 para falso y 1 para verdadero\n\n");
scanf("%1s", ptr_nuevo->respuestas+8);
}
scanf("%1s", ptr_nuevo->respuestas+9);
while (ptr_nuevo->respuestas[9] != '0' && ptr_nuevo->respuestas[9] != '1') {
fprintf(stdout, "\n\nRecuerde que sólo se admite 0 para falso y 1 para verdadero\n\n");
scanf("%1s", ptr_nuevo->respuestas+9);
}
/* fin de examen */
/* lectura respuestas desde archivo */
FILE *lectura = fopen("respuestas", "r");
fread(ptr_nuevo->f_v, 1, 10, lectura);
fclose(lectura);
/* cantidad de respuestas correctas e incorrectas */
for (j=0; j<10; j++) {
if (ptr_nuevo->respuestas[j] == ptr_nuevo->f_v[j])
ptr_nuevo->correctas++;
else
ptr_nuevo->incorrectas++;
}
/* apunta al siguiente nodo */
ptr_nuevo = ptr_nuevo->siguiente;
/* si es el último ciclo, establecer último nodo en NULL (convención) */
if (i==*(cantidad_int+contador)-1)
ptr_nuevo->siguiente = NULL;
}
/* insuficiente memoria princial */
else {
exit(EXIT_FAILURE);
}
}
/* siguiente sistema */
sistema++;
contador++;
k++;
}
If necessary, can translate it to english so it can be more easy to understand.

New Topic/Question
Reply



MultiQuote



|