Segmentation fault COSTANTE

di il
4 risposte

Segmentation fault COSTANTE

Ciao a tutti! Mi sono appena iscritta, ma vi leggo già da un po'... Sono al primo anno di Ingegneria Informatica, e sto seguendo il corso di informatica, nel quale si fa principalmente C.
Sto avendo un problema, qualsiasi programma scriva con la lettura di files, soprattutto se il nome dev'essere letto da linea di comando, mi da un errore di segmentazione. Ho provato a controllare nel libro e negli appunti ma non riesco a trovare l'errore. Vi posto uno degli ultimi con cui ho avuto problemi (si tratta di un programmino che dovrebbe leggere da riga di comando il nome del file, e ogni riga del file contiene sei campi). Il codice è abbastanza commentato, per cui dovrebbe essere chiaro.
Grazie mille a chiunque mi aiuti!
P.S.= Uso codeblocks su Ubuntu

#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#define N 20

typedef struct esame
{
char materia[N];
char nome[N];
char cognome[N];
int periodo;
int cfu;
float sup_esami;
}new_type;

int main(int argc, char* argv[])
{
FILE *fp; /*Puntatore al file*/
new_type string1; /*Struttura con cui manipolare i dati*/
char str[70]; /*Stringa di appoggio per la sscanf*/
char mat_1, mat_2, mat_3, mat_4; /*Materie più difficili per i quattro periodi*/
int max_1=0, max_2=0, max_3=0, max_4=0; /*Massimo dei crediti per i quattro periodi, già inizializzate*/
char max_mat; /*Materia più difficile*/
char cognome[20]; /*Cognome del prof. inserito dall'utente*/
int max=0; /*Crediti della materia più difficile*/
int sum, sum1; /*Somma crediti prof. inserito da tastiera e somma superamento esami per calcolare la media.*/
int i=0; /*Indice per calcolare la media*/
float media; /*Media prof.*/

/*Controllo che il numero di parametri da linea di comando sia giusto*/
if (argc!=2)
{
printf ("Errore parametri.");
return -1;
}

/*Apro il file, in modalità lettura*/
fp=fopen(argv[1], "r");

/*Verifico che il file sia aperto correttamente*/
if (fp==NULL)
{
printf ("Errore apertura file.");
return -2;
}

/*Chiedo all'utente di inserire il cognome del professore che interessa*/
printf ("Inserire cognome professore:");
scanf ("%s", cognome);

/*Inizio il ciclo che mi permettere di leggere una per una le righe del file, finchè non si arriva alla riga vuota.*/
while ((*str = fgets(str,70,fp))!=NULL)
{
/*Leggo dalla stringa i dati nel formato utile, e li salvo nella struct string1*/
sscanf (*str, "%s %s %s %d %d %f", string1.nome, string1.cognome, string1.materia, &string1.periodo, &string1.cfu, &string1.sup_esami);
/*Cerco la materia più difficile tra quelle inserite*/
if (string1.cfu>max)
strcpy(max_mat,string1.materia);
/*Per ciascun periodo ricerco la materia con il numero maggiore di crediti*/
{if (string1.periodo==1)
{
if (string1.cfu>max_1)
strcpy(mat_1,string1.materia);
}
if (string1.periodo==2)
{
if (string1.cfu>max_2)
strcpy(mat_2,string1.materia);
}
if (string1.periodo==3)
{
if (string1.cfu>max_3)
strcpy(mat_3,string1.materia);
}
if (string1.periodo==3)
{
if (string1.cfu>max_3)
strcpy(mat_1,string1.materia);
}}

if (strcmp(string1.cognome, cognome)!=0)
{
sum=sum+string1.cfu;
i++;
sum1=sum1+string1.sup_esami;
media= (float)sum1/i;
}

}

printf ("Materia + difficile: %s\n", max_mat);
printf ("Periodo 1: %s\nPeriodo 2: %s\nPeriodo 3: %s\n Periodo 4: %s\n", mat_1,mat_2,mat_3,mat_4);
printf ("Somma dei crediti prof. %s: %d\n", cognome, sum);
printf ("Media superamento esami prof. %s: %f", cognome, media);


return 0;
}

In questo caso specifico, mi fa inserire il nome del professore di cui mi interessa sapere la somma dei crediti degli esami e la media di superamento, ma poi mi da il solito "Segmentation fault."

4 Risposte

  • Re: Segmentation fault COSTANTE

    Intanto il while deve essere

    while (fgets(str,70,fp)!=NULL)

    e la sscanf

    sscanf (str, "%s %s %s %d %d %f", string1.nome, string1.cognome, string1.materia, &string1.periodo, &string1.cfu, &string1.sup_esami);


    Quello che hai scritto tu usando

    *str

    non ha senso
  • Re: Segmentation fault COSTANTE

    Sì, in effetti hai ragione: originariamente il programma era come dicevi tu, poi ho provato a cambiare un po' di "cose a caso" e ho postato quel codice... Comunque non viaggia lo stesso...
    #include <stdio.h>
    #include <stdlib.h>
    #include <string.h>
    #define N 20

    typedef struct esame
    {
    char materia[N];
    char nome[N];
    char cognome[N];
    int periodo;
    int cfu;
    float sup_esami;
    }new_type;

    int main(int argc, char* argv[])
    {
    FILE *fp; /*Puntatore al file*/
    new_type string1; /*Struttura con cui manipolare i dati*/
    char str[70]; /*Stringa di appoggio per la sscanf*/
    char mat_1, mat_2, mat_3, mat_4; /*Materie più difficili per i quattro periodi*/
    int max_1=0, max_2=0, max_3=0, max_4=0; /*Massimo dei crediti per i quattro periodi, già inizializzate*/
    char max_mat; /*Materia più difficile*/
    char cognome[20]; /*Cognome del prof. inserito dall'utente*/
    int max=0; /*Crediti della materia più difficile*/
    int sum, sum1; /*Somma crediti prof. inserito da tastiera e somma superamento esami per calcolare la media.*/
    int i=0; /*Indice per calcolare la media*/
    float media; /*Media prof.*/

    /*Controllo che il numero di parametri da linea di comando sia giusto*/
    if (argc!=2)
    {
    printf ("Errore parametri.");
    return -1;
    }

    /*Apro il file, in modalità lettura*/
    fp=fopen(argv[1], "r");

    /*Verifico che il file sia aperto correttamente*/
    if (fp==NULL)
    {
    printf ("Errore apertura file.");
    return -2;
    }

    /*Chiedo all'utente di inserire il cognome del professore che interessa*/
    printf ("Inserire cognome professore:");
    scanf ("%s", cognome);

    /*Inizio il ciclo che mi permettere di leggere una per una le righe del file, finchè non si arriva alla riga vuota.*/
    while ((fgets(str,70,fp))!=NULL)
    {
    /*Leggo dalla stringa i dati nel formato utile, e li salvo nella struct string1*/
    sscanf (str, "%s %s %s %d %d %f", string1.nome, string1.cognome, string1.materia, &string1.periodo, &string1.cfu, &string1.sup_esami);
    /*Cerco la materia più difficile tra quelle inserite*/
    if (string1.cfu>max)
    strcpy(max_mat,string1.materia);
    /*Per ciascun periodo ricerco la materia con il numero maggiore di crediti*/
    {if (string1.periodo==1)
    {
    if (string1.cfu>max_1)
    strcpy(mat_1,string1.materia);
    }
    if (string1.periodo==2)
    {
    if (string1.cfu>max_2)
    strcpy(mat_2,string1.materia);
    }
    if (string1.periodo==3)
    {
    if (string1.cfu>max_3)
    strcpy(mat_3,string1.materia);
    }
    if (string1.periodo==3)
    {
    if (string1.cfu>max_3)
    strcpy(mat_1,string1.materia);
    }}

    if (strcmp(string1.cognome, cognome)!=0)
    {
    sum=sum+string1.cfu;
    i++;
    sum1=sum1+string1.sup_esami;
    media= (float)sum1/i;
    }

    }

    printf ("Materia + difficile: %s\n", max_mat);
    printf ("Periodo 1: %s\nPeriodo 2: %s\nPeriodo 3: %s\n Periodo 4: %s\n", mat_1,mat_2,mat_3,mat_4);
    printf ("Somma dei crediti prof. %s: %d\n", cognome, sum);
    printf ("Media superamento esami prof. %s: %f", cognome, media);


    return 0;
    }
  • Re: Segmentation fault COSTANTE

    "Non viaggia" non significa nulla e non ti aiuta a risolvere ...

    Cosa succede esattamente e in quale momento?

    Vedendo il codice si può notare subito che

    char max_mat; /*Materia più difficile*/

    non è una stringa e non può essere usato come hai fatto tu.
    Non è neanche compilabile ...
  • Re: Segmentation fault COSTANTE

    E tra le altre cose ogni volta che trovi un nuovo massimo non cambi mai il valore delle varie variabili max* (se ho capito quello che vuoi fare, perché non mi é particolarmente chiaro)
Devi accedere o registrarti per scrivere nel forum
4 risposte