0

I'm comparing a string taken in input by a normal scanf with a string in a struct. This is the struct:

typedef struct{     // Tipo giocatore e i suoi dati
        int id;
        char * nome;
        char * cognome;   //<--------- this one (it means surname)
        int eta;
        char * ruolo;
        squadra team;
        char * college;
        int td;
    } giocatore;

And this is the code that work and doesn't work (?.?). I don't know why some times it works and some times it doesn't because this is the second case of a switch which has the same identical code as the first case but with the word "name" instead of "surname". Remeber that the first case work every time, the second one on is choose (lol) and the last one (3rd) contain the first problem that i explained before.

size_t ricerca(short int tipo, size_t sz, giocatore array[]){
    size_t count = 0;
    char cerca;
    switch(tipo){
    case 1:
        printf ("Inserisci il nome da cercare: ");
        scanf ("%s", &cerca);
        for (size_t i = 0; i < sz; ++i){
            if (strcmp(array[i].nome, &cerca) == 0){
                printf("ID:%d Nome:'%s' Cognome:'%s' Eta:%d Ruolo:'%s' Team:'%s' College:'%s'\n",
                    array[i].id,
                    array[i].nome,
                    array[i].cognome,
                    array[i].eta,
                    array[i].ruolo,
                    array[i].team.nome,
                    array[i].college);
                count++;
                    }
        }
        break;
    case 2:
        printf ("Inserisci il cognome da cercare: ");
        scanf ("%s", &cerca);
        for (size_t i = 0; i < sz; ++i){
            if (strcmp(array[i].cognome, &cerca) == 0){
                printf("ID:%d Nome:'%s' Cognome:'%s' Eta:%d Ruolo:'%s' Team:'%s' College:'%s'\n",
                    array[i].id,
                    array[i].nome,
                    array[i].cognome,
                    array[i].eta,
                    array[i].ruolo,
                    array[i].team.nome,
                    array[i].college);
                count++;
                    }
        }
        break;
    case 3:
        goto Cleanup;
        Cleanup: ;
        char nomesq[30];
        printf ("Inserisci il nome della squadra da cercare: ");
        scanf("%[^\n]%*c", nomesq);
        for (size_t i = 0; i < sz; ++i){
            if (strcmp(array[i].team.nome, nomesq) == 0){
                printf("ID:%d Nome:'%s' Cognome:'%s' Eta:%d Ruolo:'%s' Team:'%s' College:'%s'\n",
                    array[i].id,
                    array[i].nome,
                    array[i].cognome,
                    array[i].eta,
                    array[i].ruolo,
                    array[i].team.nome,
                    array[i].college);
                count += 1;
                    }
        }
        break;
    default:
        printf("Inserisci un valore valido\n;");
        break;
    }
    return count;
}

Thanks in advance for your patience and your help and sorry for my english :)

Jean-François Fabre
  • 137,073
  • 23
  • 153
  • 219
  • 2
    "using scanf" and "losing my mind" are often synonymous. – William Pursell Mar 17 '20 at 22:00
  • 1
    `scanf ("%s", &cerca);` is wrong: it will overwrite something outside `char cerca` memory. Use getc – Jean-François Fabre Mar 17 '20 at 22:03
  • 1
    please limit your question to 1 question. The other question is a duplicate/format is wrong should be `scanf("%29[^\n]s",nomesq);` (more here: https://stackoverflow.com/questions/1247989/how-do-you-allow-spaces-to-be-entered-using-scanf) I've edited it out. – Jean-François Fabre Mar 17 '20 at 22:08
  • I wrote that i tried that solution and it didnt work for me. It seems like my scanf can't be executed and i can't put anything, but the program go forward. Thank you for your help – Claudio Rizzi Mar 18 '20 at 15:48
  • edit: i solved with a getc which empties the buffer :) thank you, everything solved – Claudio Rizzi Mar 18 '20 at 16:42

1 Answers1

2

"sometimes it works sometimes it doesn't". I didn't test but that means undefined behaviour. And one blatant undefined behaviour is this:

char cerca;

then this:

scanf ("%s", &cerca);

this is scanning cerca as a pointer on chars. But there's not enough room for even 1 char (plus nul termination). This is a vicious bug as it doesn't even trigger a warning (type of &cerca is char * all right).

Quickfix:

char cerca[100];

then

scanf("%99s",cerca);

and change &cerca by cerca in the rest of the code (the strcmp part too, be sure to enable warnings). This is safe, and will truncate if string is too big. No overflow, no undefined behaviour.

Jean-François Fabre
  • 137,073
  • 23
  • 153
  • 219