• Najnowsze pytania
  • Bez odpowiedzi
  • Zadaj pytanie
  • Kategorie
  • Tagi
  • Zdobyte punkty
  • Ekipa ninja
  • IRC
  • FAQ
  • Regulamin
  • Książki warte uwagi

c++ pomijanie wprowadzenia danych podczas pierwszej iteracji pętli for oraz niepoprawne działanie programu

Object Storage Arubacloud
0 głosów
287 wizyt
pytanie zadane 20 września 2020 w C i C++ przez JustMeMax Nowicjusz (120 p.)

Witam,

chciałem stworzyć program do nauki słówek w języku obcym (w moim wypadku jest to angielski), który prosi o podanie liczby słówek, dodanie najpierw obcych potem przetłumaczonych słów, a na końcu losuje słowa z tabeli i prosi o ich przetłumaczenie. Wszystko to w nieskończonej pętli for(;;). Po udzieleniu odpowiedzi przez użytkownika program wyświetla komunikat:

Brawo! lub Niepoprawnie! Jest to [poprawna odpowiedz]

Zmienic jezyk? (C)

Kontynuowac? (Y/N)

Dodatkowo program ma zmienić język, na który mamy tłumaczyć słówka poprzez naciśnięcie klawisza C.

Program zapisuje ilość słów do nauki w zmiennej i na tej podstawie tworzy tabelę string wordsENG[j] oraz string wordsPL[j]. Dane do tabeli wprowadzane są poprzez pętle for(int i = 0; i<j; i++) oraz getline (cin, wordsENG[i])

Problemy polegają na: 


1. Pętla for pytająca o wprowadzenie słówek z języka obcego pomija pierwszą iteracje wyrzucając na ekran:

Ile slowek chcesz dodac?
3 [dane użytkownika]
Podaj slowa w jezyku obcym:
Podaj 1 slowo: Podaj 2 slowo:

Uniemożliwia to wprowadzenie pierwszej zmiennej.

Co ciekawe pod tym względem druga pętla działa bez zarzutów więc jeśli program wylosuje wordsENG[0] na ekranie zobaczymy:

[             ]  <--- puste miejsce

Podaj tlumaczenie na polski:

jeśli podamy dane z wordsPL[0] otrzymamy komunikat o poprawnym tłumaczeniu.

 

2. Funkcja zmiany języka nie działa. Program odczytuje naciśnięcie klawisza C, ale później pojawia się pusty ekran bez możliwości jakiejkolwiek interakcji. Brak informacji o błędzie lub o zakończeniu działania programu. Pozostaje zamknąć program. 

Sytuacja z 2 punktu zdarza się również, gdy zamiast nacisnąć lub N naciśniemy dowolne inne klawisze.

 

3. Czy istnieje możliwość blokady wprowadzania danych z klawiatury na określony czas? Jest to pytanie związane z komunikatem na początku programu, który jest zapisany jako komentarz. Czytałem o funkcji BlockInput(), ale nie potrafiłem jej zaimplementować. Natomiast funkcja Sleep() pozwala zatrzymać program na dany okres czasu, ale użytkownik dalej może wprowadzać dane z klawiatury przez co może on nieświadomie podać nieodpowiednie dane do zapytania Ile slowek chcesz dodac? i zatwierdzić je powodując błąd programu przed jego właściwym uruchomieniem.

 

Czy moglibyście mi pomóc? Za wszelką konstruktywną krytykę oraz pomoc dziękuję z góry.

Github (podaję link w razie gdyby kod poniżej byłby za długi): https://gist.github.com/CodeMaks360/61525493cfcbef05ef4f191a3deadc07

 

#include <iostream>
#include <windows.h>
#include <ctime>
#include <conio.h>
#include <algorithm>
#include <string>

using namespace std;

int main()
{
    // 0 - obce na PL; 1 - PL na obce
    bool lang = 0;

/*  //komunikat
    cout << "UWAGA! JESLI PODCZAS ZAPYTANIA '(Y/N)' NIE NACISNIESZ ZADNEJ Z DWOCH WYMIENIONYCH LITER \nPROGRAM PRZESTANIE DZIALAC POPRAWNIE!" << endl;
    Sleep(8000);

    cout << "Pamietaj aby dodawac slowa i ich tlumaczenia w tej samej kolejnosci!" << endl;

    Sleep(5000);

    cout << "Milej nauki!" << endl;

    Sleep(3000);

    system("cls");
*/

    //obce slowa
    int j;

    cout << "Ile slowek chcesz dodac?" << endl;
    do
    {
        cin >> j;
    }while(j <= 0);

    cout << "Podaj slowa w jezyku obcym:" << endl;

    string wordsENG[j];
    for(int i = 0; i<j; i++)
    {
        cout << "Podaj " << i+1 << " slowo: ";
        getline (cin, wordsENG[i]);
        for_each(wordsENG[i].begin(), wordsENG[i].end(), [](char & c) {
            c = ::tolower(c);
        });
    }

    //tlumaczenie
    cout << "Teraz podaj ich tlumaczenie:" << endl;

    string wordsPL[j];
    for(int i = 0; i<j; i++)
    {
        getline (cin, wordsPL[i]);
        for_each(wordsPL[i].begin(), wordsPL[i].end(), [](char & c) {
            c = ::tolower(c);
        });
    }
    //wejscie do glownej petli
    system("cls");
    char klik;

    klik = 121;

    //glowna petla
    for(;;)
    {
        switch(klik)
        {
            case 121:
            {
                switch(lang)
                {
                    case 0:
                    {
                        srand(time(NULL));
                        int los = rand() % j;
                        cout << wordsENG[los] << endl;
                        cout << "Podaj tlumaczenie na polski: ";
                        string PL;
                        cin >> PL;
                        for_each(PL.begin(), PL.end(), [](char & c) {
                            c = ::tolower(c);
                        });

                        if(PL == wordsPL[los])
                        {
                            cout << "Brawo!" << endl;
                            cout << "Zmienic jezyk? (C)" << endl;
                            cout << "Kontynuowac? (Y/N)" << endl;
                            klik = getch();
                            system("cls");
                        }
                        else
                        {
                            cout << "Niepoprawnie! Jest to " << wordsPL[los] << endl;
                            cout << "Zmienic jezyk? (C)" << endl;
                            cout << "Kontynuowac? (Y/N)" << endl;
                            klik = getch();
                            system("cls");
                        }
                    }break;

                    case 1:
                    {
                        srand(time(NULL));
                        int los = rand() % j;
                        cout << wordsPL[los] << endl;
                        cout << "Podaj tlumaczenie na angielski: ";
                        string ENG;
                        cin >> ENG;
                        for_each(ENG.begin(), ENG.end(), [](char & c) {
                            c = ::tolower(c);
                        });

                        if(ENG == wordsENG[los])
                        {
                            cout << "Brawo!" << endl;
                            cout << "Zmienic jezyk? (C)" << endl;
                            cout << "Kontynuowac? (Y/N)" << endl;
                            klik = getch();
                            system("cls");
                        }
                        else
                        {
                            cout << "Niepoprawnie! Jest to " << wordsENG[los] << endl;
                            cout << "Zmienic jezyk? (C)" << endl;
                            cout << "Kontynuowac? (Y/N)" << endl;
                            klik = getch();
                            system("cls");
                        }
                    }break;

                    default:
                    {

                    }break;
                }break;

                case 99:
                {
                    lang = !(lang);
                }break;

                case 110:
                {
                    return 0;
                }break;

                default:
                {

                }break;
            }

        }

    }

    return 0;
}

 

1 odpowiedź

+1 głos
odpowiedź 20 września 2020 przez j23 Mędrzec (194,920 p.)

1.

cin >> j;
...

getline (cin, wordsENG[i]);

Daj tak:

getline (cin >> ws, wordsENG[i]);

Czytanie liczby pozostawia znak końca linii, co jest interpretowane przez getline jako pusta linia.

Podziel kod na funkcje, bo źle się go czyta. Pozbądź się też magic numbers - tam, gdzie chodzi o znaki, niech będą literały znakowe (tak, w case'ach możesz ich użyć).

 

int j;
...
string wordsENG[j];
...

string wordsPL[j];
...

Takie rzeczy to nie w C++. Użyj klasy std::vector.

Podobne pytania

0 głosów
2 odpowiedzi 193 wizyt
0 głosów
1 odpowiedź 300 wizyt
+1 głos
1 odpowiedź 117 wizyt

92,555 zapytań

141,402 odpowiedzi

319,546 komentarzy

61,939 pasjonatów

Motyw:

Akcja Pajacyk

Pajacyk od wielu lat dożywia dzieci. Pomóż klikając w zielony brzuszek na stronie. Dziękujemy! ♡

Oto polecana książka warta uwagi.
Pełną listę książek znajdziesz tutaj.

Akademia Sekuraka

Kolejna edycja największej imprezy hakerskiej w Polsce, czyli Mega Sekurak Hacking Party odbędzie się już 20 maja 2024r. Z tej okazji mamy dla Was kod: pasjamshp - jeżeli wpiszecie go w koszyku, to wówczas otrzymacie 40% zniżki na bilet w wersji standard!

Więcej informacji na temat imprezy znajdziecie tutaj. Dziękujemy ekipie Sekuraka za taką fajną zniżkę dla wszystkich Pasjonatów!

Akademia Sekuraka

Niedawno wystartował dodruk tej świetnej, rozchwytywanej książki (około 940 stron). Mamy dla Was kod: pasja (wpiszcie go w koszyku), dzięki któremu otrzymujemy 10% zniżki - dziękujemy zaprzyjaźnionej ekipie Sekuraka za taki bonus dla Pasjonatów! Książka to pierwszy tom z serii o ITsec, który łagodnie wprowadzi w świat bezpieczeństwa IT każdą osobę - warto, polecamy!

...