Problemi di esecuzione del main

di il
14 risposte

Problemi di esecuzione del main

Ciao a tutti.
Vi scrivo poichè, provando una traccia di programmazione C, ho riscontrato un problema in fase di esecuzione.
La traccia è la seguente:
Il proprietario di una catena di supermercati intende creare una tabella per una più efficiente gestione dei suoi
supermercati. Per ogni supermercato il sistema deve memorizzare: il nome e il cognome del responsabile del
supermercato; l’indirizzo del supermercato (ad Esempio Via: Roma, 4 e città: Taranto; il numero di dipendenti, il
fatturato dell’ultimo anno.
Il programma dovrà consentire di:
? caricare le informazioni della tabella;
? visualizzare i dati del supermercato il cui responsabile è inserito in input dal proprietario della
catena;
? visualizzare quanti supermercati sono presenti nella città inserita in input dal proprietario della
catena;
? visualizzare il supermercato che ha il maggior numero di dipendenti.
Precisamente sono bloccato al secondo punto del programma, quello del visualizzare i dati inserendo il cognome (ho scelto così ) del responsabile del supermercato.
In fase di compilazione non da alcun errore sintattico, ma durante l'esecuzione il programma crasha.
Posto qui sotto il mio codice completo, sperando qualcuno di voi possa aiutarmi
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#define max 10
struct Sdata{
char nome[10];
char cognome[15];
char indirizzo[30];
char citta[15];
int dip;
float fatt;};

typedef struct Sdata sup;

int main()
{int n,i,c;
char cognp[15];
printf("Inserire il numero dei supermercati da registrare:");
scanf("%d",&n);
if (n>max){                                         //Controllo che il numero di supermercati da registrare non superi un massimo indicato.
    printf("\n\aErrore,non superare un massimo di 10 supermercati da registrare!");
    return 0;
}
sup supermercati[n];
for (i=0;i<n;i++){                          //Registrazione dei dati di ogni supermercato
printf("\nSupermercato n.%d",i);
fflush (stdin);
    printf("\nInserire nome del proprietario:");
    scanf("%c",&supermercati[i].nome);
    fflush (stdin);
    printf("\nInserire cognome del proprietario:");
    scanf("%s",&supermercati[i].cognome);
    fflush (stdin);
    printf("\nInserire l'indirizzo del supermercato:");
    scanf("%s",&supermercati[i].indirizzo);
    fflush (stdin);
    printf("\nInserire la citta' del supermercato:");
    scanf("%s",&supermercati[i].citta);
    fflush (stdin);
    printf("\nInserire il numero di dipendenti:");
    scanf("%d",&supermercati[i].dip);
    fflush (stdin);
    printf("\nInserire il fatturato di quest'anno (in euro):");
    scanf("%f",&supermercati[i].fatt);
    fflush (stdin);
}

system("pause");
printf("\nVisualizzazione dati:\n");
printf("Inserire il cognome del responsabile del supermercato:");
scanf("%s",&cognp);
fflush (stdin);
i=0;

while (c!=0){
    c==strcmp(cognp[15],supermercati[i].cognome[15]);
    i++;
}
if (c==0){
printf("\nSupermercato %d",i);
printf("\nNome e cognome del responsabile: %s %s",supermercati[i].nome,supermercati[i].cognome);
printf("\nIndirizzo e citta':%s,%s",supermercati[i].indirizzo,supermercati[i].citta);
printf("\nNumero dipendenti: %d",supermercati[i].dip);
printf("\nFatturato annuo: %f",supermercati[i].fatt);};


    return 0;
}

14 Risposte

  • Re: Problemi di esecuzione del main

    Per l'input di una stringa devi usare %s e non %c

    scanf("%c",&supermercati.nome);

    e poi questa

    c==strcmp(cognp[15],supermercati.cognome[15]);

    è sbagliata ... dovrebbe essere

    c = strcmp(cognp, supermercati.cognome);
  • Re: Problemi di esecuzione del main

    Scanf() riceve in input il puntatore alla variabile da leggere;
    il nome di una stringa rappresenta gia' un puntatore;
    quindi per leggere un dato stringa bisogna fare: scanf("%s", supermercati.cognome);
    se anteponi il simbolo & dici a scanf() di leggere un puntatore a un puntatore,
    non una stringa!

    non va bene:
    c==strcmp(cognp[15], supermercati.cognome[15]);

    devi usare:
    c=strcmp(cognp, supermercati.cognome);

    il contatore i dopo l'uscita dal ciclo while non corrisponde
    alla struct cercata, ma a quella successiva (infatti e' stato incrementato
    di 1 dopo il confronto strcmp());

    le istruzioni per mostrare la struct trovata dovrebbero trovarsi
    all'interno del ciclo, prima dell'incremento di i;

    poi, come condizione per l'uscita dal ciclo, non dovresti usare
    il raggiungimento di c uguale a 0 (che potrebbe anche non verificarsi mai,
    se il cognome richiesto non c'e'); e' meglio usare un ciclo (for o while)
    che ti faccia leggere tutte le struct inserite; cosi' potresti visualizzare
    tutte le struct cercate, se due o piu' supermercati hanno un direttore
    con lo stesso cognome. Bisogna pensare a tutti i casi possibili.

    Per visualizzare un dato con printf():
    printf("\n%s%s\n", "Cognome responsabile: ", supermercati.cognome);
  • Re: Problemi di esecuzione del main

    Ok ragazzi, sono riuscito a risolvere seguendo le vostre indicazioni. Ho inserito tutto in un ciclo FOR che faceva confrontare le stringhe con tutte le strutture e , se non si è trovata una stringa uguale in nessuna struttura dati, viene stampato un messaggio di errore. Vi posto qui sotto il pezzo di codice modificato per mostrarvi.
    for (i=0;i<=n;i++){
    c=strcmp(cognp, supermercati[i].cognome);
    if (c==0){
    printf("\nSupermercato %d",i);
    printf("\nNome e cognome del responsabile: %s %s",supermercati[i].nome,supermercati[i].cognome);
    printf("\nIndirizzo e citta':%s,%s",supermercati[i].indirizzo,supermercati[i].citta);
    printf("\nNumero dipendenti: %d",supermercati[i].dip);
    printf("\nFatturato annuo: %f",supermercati[i].fatt);};
    if (c!=0 && i==n){
        printf("\n\aSupermercato non trovato\n");
    };};


    Korr non ho capito una sola cosa
    Per visualizzare un dato con printf():
    printf("\n%s%s\n", "Cognome responsabile: ", supermercati.cognome);

    Perchè dovrei fare così? C'è una spiegazione? Perchè a me è stato spiegato diversamente in università.

    Grazie a tutti comunque, ora continuo gli altri punti della traccia sperando di non riscontrare più errori
  • Re: Problemi di esecuzione del main

    Di quale errore parli?

    Occhio anche perché se n è il valore massimo non devi scrivere

    i<=n

    ma

    i<n
  • Re: Problemi di esecuzione del main

    dr_drew ha scritto:


    Per visualizzare un dato con printf():

    printf("\n%s%s\n", "Cognome responsabile: ", supermercati.cognome);

    Perchè dovrei fare così?


    Hai un array di supermercati: Numero 0, numero 1, numero 2 ecc.
    Nella struttura che descrive un supermercato, c'è un membro "cognome".
    Quindi, per visualizzare il cognome del gestore di supermercato #2, scrivi

    printf("\n%s%s\n", "Cognome responsabile: ", supermercati[2].cognome);

    Logico, no? Rileggi le tue notizie dell'università, forse erano un po' ambigue.
  • Re: Problemi di esecuzione del main

    Forse tu intendi che utilizzate questa forma

    printf("\nCognome responsabile: %s\n", supermercati[2].cognome);

    ma è equivalente ...
  • Re: Problemi di esecuzione del main

    oregon ha scritto:


    Forse tu intendi che utilizzate questa forma

    printf("\nCognome responsabile: %s\n", supermercati[2].cognome);

    ma è equivalente ...
    Giusto, ce n'è un %s in troppo, che si è infilato nel post di Korr:

    Korr ha scritto:


    Per visualizzare un dato con printf():
    printf("\n%s%s\n", "Cognome responsabile: ", supermercati.cognome);


    Ma equivalente, sei sicuro? Come reagisce C se prometti due argumenti e gli dai solo uno?
    G++, per esempio, ti dà un' exception:

    #include <stdio.h>
    
    int main(int argc, char* argv[]) {
    	__asm("INT $3");
      printf("%s%s\n", "Una stringa!");
    }
    Come vedi, carica due parametri invece di uno - e produce un bel crash:
    0040134E                  ³.  CC                     int3
    0040134F                  ³.  C74424 04 24304000     mov dword ptr [local.3], offset 00403024    ; ³<%s> => "Una stringa!"
    00401357                  ³.  C70424 31304000        mov dword ptr [local.4], offset 00403031    ; ³format => "%s%s
    "
    0040135E                  ³.  E8 2D080000            call <jmp.&msvcrt.printf>                   ; ÀMSVCRT.printf
  • Re: Problemi di esecuzione del main

    Se le struct dell'array sono n, gli indici i relativi
    vanno da 0 a (n-1); il primo elemento ha indice 0,
    il secondo 1, ..., l'ultimo (n-1).

    Volevo proporre un uso alternativo di printf(),
    che secondo me puo' rendere piu' leggibili le istruzioni
    con molti dati.

    Sul mio compilatore (gcc 4.6.3 per linux ubuntu) compilazione ed esecuzione
    avvengono regolarmente; le due specifiche %s si riferiscono alle
    due stringhe "Cognome responsabile" e supermercati.cognome.

    La condizione (c!=0 && i==n), per verificare se la struct richiesta
    e' stata trovata, rende 0 (cioe' falso) se la struct cercata c'e',
    ma non e' l'ultima.

    Potresti risolvere usando una variabile char trovato, da inizializzare a 0
    prima del ciclo e che riceva 1 in caso di presenza del dato cercato;
    poi verificandone il valore dopo il ciclo di ricerca.

    Oppure potresti usare un contatore delle struct trovate.

    Il punto e virgola dopo la graffa di chiusura non e' necessario:
    aggiunge un'istruzione vuota.
  • Re: Problemi di esecuzione del main

    Korr ha scritto:


    le due specifiche %s si riferiscono alle due stringhe "Cognome responsabile" e supermercati.cognome.


    Hai ragione, scusa! Non so piu' contare argomenti
  • Re: Problemi di esecuzione del main

    Infatti, per questo dicevo equivalenti
  • Re: Problemi di esecuzione del main

    Rettifico una frase:
    la condizione (c!=0 && i==n), per verificare se la struct richiesta
    e' stata trovata, rende 1 (vero, cioe' non trovato) se la struct cercata c'e',
    ma non e' l'ultima; infatti c, al momento del confronto, ha il valore
    risultante dall'esame dell'ultima struct dell'array.
  • Re: Problemi di esecuzione del main

    Ragazzi modificando il programma funziona tutto bene, eccetto una cosa ( risolta usando una gets) , nella visualizzazione dati.
    Quando infatti stampavo a schermo l'indirizzo e la città, a prescindere dal modo in cui potevo farlo ( es: 1 printf con due stringhe, 2 printf per indirizzo e per città) mi usciva a schermo solo la scritta "via". La stringa quindi era "troncata".
    Ho risolto questo problema usando, nell'acquisizione della stringa per l'indirizzo , l'istruzione gets ma vorrei onestamente capire quale può essere stata la causa del mio problema.
  • Re: Problemi di esecuzione del main

    Succede perché la scanf interrompe l'input appena incontra uno spazio.

    Meglio della gets utilizza la fgets (con stdin)
  • Re: Problemi di esecuzione del main

    Potresti indicarmi la sintassi della fgets? E perchè è meglio ?
Devi accedere o registrarti per scrivere nel forum
14 risposte