Komunikat z printf wyświetla się podwójnie (jezyk C)

0

Dzień dobry,
Program przeliczający temperatury ma działać dopóki użytkownik go nie zakończy (wybierając opcję 7 w switch case). Podczas wybierania z menu po raz pierwszy dowolnej opcji wszystko działa, ale przy wyborze drugiego działania komunikat z printf("\nWybierz dzialanie: "); wyświetla się podwójnie. Dlaczego tak się dzieje i jak to naprawić?

int main()
{

    printf("Opcje:\n\n1. FtoC\n2. FtoK\n3. CtoF\n4. CtoK\n5. KtoC\n6. KtoF\n7. Zakoncz program\n8. Pokaz zawartosc tablicy\n ");
    printf("\nWybierz dzialanie (1, 2, 3, 4, 5, 6, 7, 8): ");  scanf("%c", &symbol);

    while(1)
    {

        switch(symbol)
        {

            case '1':
                printf("\nFarhenheit to Celsius: \n");
                printf("Podaj F: "); scanf("%f", &F);
                stopnie = 'F';
                C = FtoC(F, C);
                temp = F;
                sprawdz(temp, stopnie);
                if(sprawdz(temp, stopnie)==1){printf("Nie ma takiej temperatury!\n");}
                else if(sprawdz(temp, stopnie)==0){printf("%3.0f %6.1f \n", F, C);}
                symbolA = 'F';
                symbolB = 'C';
                tempA = F;
                tempB = C;
                tablice(symbolA, symbolB, tempA, tempB);
            break;

            case '2':
                printf("\nFarhenheit to Kalwin: \n");
                printf("Podaj F: "); scanf("%f", &F);
                stopnie = 'F';
                K = FtoK(F, K);
                temp = F;
                sprawdz(temp, stopnie);
                if(sprawdz(temp, stopnie)==1){printf("Nie ma takiej temperatury!\n");}
                else if(sprawdz(temp, stopnie)==0){printf("%3.0f %6.1f \n", F, K);}
                symbolA = 'F';
                symbolB = 'K';
                tempA = F;
                tempB = K;
                tablice(symbolA, symbolB, tempA, tempB);
             break;![250345600_1579728652387193_1525892995449987074_n.jpg](https://4programmers.net/uploads/115161/3t32qLj8zgX4hxTudF6h8Txq17V6vCOouTvmOvl0.jpg)

            case '3':
                printf("\nCelsius to Fahrenheit: \n");
                printf("Podaj C: "); scanf("%f", &C);
                stopnie = 'C';
                F = CtoF(C, F);
                temp = C;
                sprawdz(temp, stopnie);
                if(sprawdz(temp, stopnie)==1){printf("Nie ma takiej temperatury!\n");}
                else if(sprawdz(temp, stopnie)==0){printf("%3.0f %6.1f \n", C, F);}
                symbolA = 'C';
                symbolB = 'F';
                tempA = C;
                tempB = F;
                tablice(symbolA, symbolB, tempA, tempB);
            break;

            case '4':
                printf("\nCelsius to Kalwin: \n");
                printf("Podaj C: "); scanf("%f", &C);
                stopnie = 'C';
                K = CtoK(C, K);
                temp = C;
                sprawdz(temp, stopnie);
                if(sprawdz(temp, stopnie)==1){printf("Nie ma takiej temperatury!\n");}
                else if(sprawdz(temp, stopnie)==0){printf("%3.0f %6.1f \n", C, K);}
                symbolA = 'C';
                symbolB = 'K';
                tempA = C;
                tempB = K;
                tablice(symbolA, symbolB, tempA, tempB);
            break;

            case '5':
                printf("\nKalwin to Celsius: \n");
                printf("Podaj K: "); scanf("%f", &K);
                stopnie = 'K';
                C = KtoC(C, K);
                temp = K;
                sprawdz(temp, stopnie);
                if(sprawdz(temp, stopnie)==1){printf("Nie ma takiej temperatury!\n");}
                else if(sprawdz(temp, stopnie)==0){printf("%3.0f %6.1f \n", K, C);}
                symbolA = 'K';
                symbolB = 'C';
                tempA = K;
                tempB = C;
                tablice(symbolA, symbolB, tempA, tempB);
            break;

            case '6':
                printf("\nKalwin to Fahrenheit: \n");
                printf("Podaj K: "); scanf("%f", &K);
                stopnie = 'K';
                F = KtoF(K, F);
                temp = K;
                if(sprawdz(temp, stopnie)==1){printf("Nie ma takiej temperatury!\n");}
                else if(sprawdz(temp, stopnie)==0){printf("%3.0f %6.1f \n", K, F);}
                symbolA = 'K';
                symbolB = 'F';
                tempA = K;
                tempB = F;
                tablice(symbolA, symbolB, tempA, tempB);
            break;

            case '7':
                return 0;
            break;

            case '8':
                printf("Zapisane wartosci: \n");
                for(int i=0; i<n; i++)
                {
                    printf("%d. %f%c ---> %f%c\n", i, dana[i], from[i], wynik[i], to[i]);
                }
            break;

            /*default:
                printf("\nError! Nie ma takiej opcji.\n");*/
        }

        printf("\nWybierz dzialanie: "); scanf("%c", &symbol);  //"Wybierz dzialanie" wyswietla sie podwojnie
    }

    return 0;
}
0

Scanf czyta też enter, który naciskasz po wpisaniu znaku. Zmień scanf na scanf(" %c", &symbol); (spacja przed %) i powinno być ok. Więcej informacji tutaj https://stackoverflow.com/questions/5240789/scanf-leaves-the-new-line-char-in-the-buffer

1

Polecam poczytać dokumentację scanf.
Szczególnie skupiść isię na opsie działania napisu formatu: %f oraz %c.
%f pomija dowolną liczbę białych znaków a następnie próbuje wczytać liczbę. Znak, który nie stanowi części liczby nie zostaje usunięty.
%c wczytuje dowolny znak w tym białe znaki.

Ergo

  1. podczas pieszej iteracji, pierwszy wczytywany znak jest to to co użytkownik wpisze jako pierwsze (czyli znak wyboru).
  2. Potem wczytywana jest liczba za pomocą %f czyli białe znaki są pomijane, wczytywane są znaki liczby, pierszy znak nie bedący częścią liczby pozostaje w buforze
  3. Tym pierwszym znakiem jest \n
  4. scanf("%c", &symbol) wczytuje kolejny znak, a ten jest znakiem końca linii.

Jednym z możliwych rozwiązań jest pominięcie białych znaków (jak w odpowidzi wyzej, ale uzasadnienie jest nieprawidłowe).

Jednak lepszy rozwiązanie byłoby porzucenie char symbol na rzecz int symbol (ja bym zmienił nazwę na wybor) i użycie scanf("%d", &symbol);.
Przydała by się tez jakaś obsługa błędów.
Zwróć uwagę, że jeśli liczba opcji urośnie ponad 9 wyczytywanie znaku stanie się bezużyteczne.

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