Koło fortuny

0

Mam z poniższym kodem jeden problem (i zapewne jeszcze trochę o których nawet nie wiem, a Was zabolą oczy), a mianowicie - ustawiłam ilość prób na 25, każde wpisanie litery skutkuje dwukrotną inkrementacją licznika prób w pętli, jakby odczytywane i sprawdzane zostawały dwa znaki, program kończy się po połowie zadeklarowanej ilości prób a prośba o podanie litery wyświetla się za każdym razem podwójnie, jeśli podam dwie litery potrójnie itd. Gdzie leży problem?

#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <time.h>
int main ()
{
    char **zbior = (char**) malloc (5 * sizeof(char*));
    for(int i=0;i<5;i++)
    {
        zbior[i] = (char*) malloc (30 * sizeof(char*));
    }
    zbior[0] = "co w trawie piszczy";
    zbior[1] = "marchewkowe pole";
    zbior[2] = "gibraltar";
    zbior[3] = "stany zjednoczone";
    zbior[4] = "rwa kulszowa";

    char word[30];
    char input[30];
    char litera;

//Losowanie hasla
    int losowana;
    srand(time(NULL));
    losowana = rand() % 5;
    if (losowana==0) strcpy(word,zbior[0]);
    else if (losowana==1) strcpy(word,zbior[1]);
    else if (losowana==2) strcpy(word,zbior[2]);
    else if (losowana==3) strcpy(word,zbior[3]);
    else if (losowana==4) strcpy(word,zbior[4]);

    strcpy(input, word);

//Szyfrowanie pola do odgadywania
    for(int i=0;word[i]!=NULL;i++)
    {
        if(word[i]!=' ')
        input[i]='_';
        else
        input[i]=' ';
    }
    printf("slowo: %s\n", input);

    int licznikProb=0;
    while(licznikProb<=25)
    {


        printf("Podaj litere: ");
        scanf("%c", &litera);
        licznikProb++;
        for (int i=0; word[i]!=NULL; i++)
        {
            if(litera==word[i])
                input[i]=litera;
        }

        printf("slowo: %s", input);
        if(strcmp(word,input)==0)
        {
            printf("\nWygrales!"); break;
        }

    }
    if (licznikProb>25) puts("\nWykorzystano wszystkie proby. Koniec gry.");

//Zwalnianie pamieci
    for (int i=0;i<5;i++)
    {
        free (zbior[i]);
        zbior[i]=NULL;
    }
    free(zbior);
    return 0;



}

3
scanf("%c", &litera);

Jeśli wpisujesz np. x<enter> to <enter> jest traktowane jako osobny znak - \n

scanf("%c", &litera);
if(litera == '\n')
    continue;
3

Skoro alokujesz bufory, czyli są zdolne do przyjęcia danych. Robi się to przez strcpy().

*( W tym prostym programie nie występuje pewien konflikt. Tu można zapytać, czy alokowanie jest konieczne, skoro przypisujesz stałe stringi. Można by było to zrobić "zamiast", tzn od razu przypisać.
Jednak w ogólnym przypadku alokowanie to jest rozwiązanie OK, na przykład w miarę rozwoju programu stringi by pochodziły z pliku, czy w inny sposób "dynamiczne". )
*


for(int i=0;i<5;i++)
    {
        zbior[i] = (char*) malloc (30 * sizeof(char*));
    }
    strcpy(zbior[0], "co w trawie piszczy");
    strcpy(zbior[1], "marchewkowe pole");
// itd

W dłuższych sekwencjach wyrażeń jak ta, używa się switch ... case, to jest uważane za lepsze pod względem stylu (poczytaj).
Tu jednak warto zauważyć, że ta sama liczba występuje dwa razy, jest taka sama.

Więc


if (losowana==0) strcpy(word,zbior[0]);
    else if (losowana==1) strcpy(word,zbior[1]);
    else if (losowana==2) strcpy(word,zbior[2]);
    else if (losowana==3) strcpy(word,zbior[3]);
    else if (losowana==4) strcpy(word,zbior[4]);

można zmienić na

   // mamy pewność, ze 'losowana jest 0,,4 - jak nie, trzeba by sprawdzić
  strcpy(word,zbior[losowana]);

W konsekwencji zagadnienia pierwszego tracisz alokowane wskaźniki (zamazujesz je adresami stałymi). I zwalniając śmieci jest UB - Udefined Behavbiour czyli rozumieć jako błąd, który może się nie ujawnić. Więc w nie poprawionym kodzie to by było źle - ale przecież poprawiamy :)

//Zwalnianie pamieci
    for (int i=0;i<5;i++)
    {
        free (zbior[i]);
        zbior[i]=NULL;
    }

1 użytkowników online, w tym zalogowanych: 0, gości: 1