diff --git a/du4/program b/du4/program new file mode 100755 index 0000000..4393c16 Binary files /dev/null and b/du4/program differ diff --git a/du4/program.c b/du4/program.c new file mode 100644 index 0000000..8b5bb76 --- /dev/null +++ b/du4/program.c @@ -0,0 +1,132 @@ +#include //pripojím si potrebné knižnice +#include +#include + +#define VELKOST_VSTUPU 50 //zadefinujem konštanty +#define POCET_CISEL 500 + +int najdiNepovoleneZnaky(char* vstup); //inicializujem vlastné funkcie +char priklad(char *vstup, float *prveCislo, float *druheCislo, float *zadanyVysledok); +int kontrolaViacnasobnejOperacie(char* priklad, char matematickaOperacia); +float vypocitaj(float cislo1, float cislo2, char matematickaOperacia); +void mazanie_znakov_v_retazci(char* vstup, char nepotrebnyZnak); + +int main() { + int pocetRiadkov, i, obsahNepovolenychZnakov; + + float prveCisla[POCET_CISEL]; //inicializujem polia, do ktorých budem ukladať potrebné čísla + float druheCisla[POCET_CISEL]; + float vysledky[POCET_CISEL]; + float kontrolneVysledky[POCET_CISEL]; + + memset(prveCisla, 0, POCET_CISEL * sizeof(float)); //vykonám počiatočnú inicializáciu pamäte + memset(druheCisla, 0, POCET_CISEL * sizeof(float)); + memset(vysledky, 0, POCET_CISEL * sizeof(float)); + memset(kontrolneVysledky, 0, POCET_CISEL * sizeof(float)); + + int chybovyStav[POCET_CISEL]; //do poľa budem ukladať záznam o správnosti formátu príkladu + memset(chybovyStav, 0, POCET_CISEL); + + char vstup[VELKOST_VSTUPU]; //inicializujem polia pre načítanie príkladov + char* stav_vstupu; + char matematickaOperacia; //do pamäte si individuálne zapíšem aritmetickú operáciu príkladu + + for (i = 0; i < POCET_CISEL; i++) { //v cykle budem načítavať príklady + stav_vstupu = fgets(vstup, VELKOST_VSTUPU, stdin); //načítam príklad + if (stav_vstupu == NULL) return 0; //skontrolujem, či sa mi príklad podarilo úspešne načítať a ak nie, tak program ukončím + else if (strcmp(vstup, "\n") == 0) break; + + mazanie_znakov_v_retazci(vstup, ' '); //zo zadaného príkladu odstránom všetky medzery zadané pri vstupe + + obsahNepovolenychZnakov = najdiNepovoleneZnaky(vstup); //skontrolujem, či používateľ nazadal do príkladu nepovolené znaky + if (obsahNepovolenychZnakov == EXIT_FAILURE) chybovyStav[i] = obsahNepovolenychZnakov; //ak ich zadal, tak informáciu o danej skutočnosti zaznamená do poľa s výsledkami + else { + matematickaOperacia = priklad(vstup, &prveCisla[i], &druheCisla[i], &vysledky[i]); //v príklade vyhľadám príslušnú aritmetickú operáciu + + obsahNepovolenychZnakov = kontrolaViacnasobnejOperacie(vstup, matematickaOperacia); //následne ešte skontrolujem to, či bol príklad zadaný v správnom formáte + if (obsahNepovolenychZnakov == EXIT_FAILURE) chybovyStav[i] = obsahNepovolenychZnakov; //ak je príklad zapísaný v nesprávnom formáte, tak program ukončím + else kontrolneVysledky[i] = vypocitaj(prveCisla[i], druheCisla[i], matematickaOperacia); //vyčíslim skutočnú hodnotu príkladu + } + } + + pocetRiadkov = i; //uložím si hodnotu načítaných vstupov, pretože nemusím zakaždým využiť celú pamäť a to potom môže spôsobiť nepredvidateľné správanie programu + + for (i = 0; i < pocetRiadkov; i++) { + if (chybovyStav[i] == EXIT_FAILURE) printf("CHYBA\n"); + else if (kontrolneVysledky[i] == vysledky[i]) printf("OK\n"); + else printf("ZLE\n"); + } + + return 0; +} + +int najdiNepovoleneZnaky(char* vstup) { //funkcia kontroluje výskyt nepovolených znakov v zadanom príklade + char nepovoleneZnaky[] = "abcdefghijklmnopqrstuvwxyz&\\|()°;ľščťžýáíéúäô§!_.:,?<>€ĐŁł[]{}&@#"; //vytvorím zoznam nepovoelných znakov + int pocetNepovolenychZnakov = strlen(nepovoleneZnaky), j; //zadefinujem si potrebné premenné a zistím počet nepovolených znakov + + for (j = 0; j <= pocetNepovolenychZnakov - 1; j++) { //v cykle skontrolujem, či sa v zadanom príklade nachádza niektorý z nepovolených znakov + if (strchr(vstup, nepovoleneZnaky[j]) != NULL) return EXIT_FAILURE; //ak sa v príklade nachádza niektorý z nepovolených znakov, tak vrátim EXIT_FAILURE + } + + return EXIT_SUCCESS; //inak vrátim EXIT_SUCCESS +} + +char priklad(char* vstup, float *prveCislo, float *druheCislo, float *zadanyVysledok) { //funkcia načíta čísla do jednotlivých polí podľa príslušnosti a vypočíta kontrolných výsledok + char matematickaOperacia, rovnaSa; + sscanf(vstup, "%f %c %f %c %f", &*prveCislo, &matematickaOperacia, &*druheCislo, &rovnaSa, &*zadanyVysledok); + + return matematickaOperacia; +} + +int kontrolaViacnasobnejOperacie(char* priklad, char matematickaOperacia) { //funkcia skontroluje viacnásobný výskyt nájdenej aritmetickej operácie, operácie = a výskytu iných predtým nezachytených nepovolených znakov iných operácií + int pocetRovnaSa = 0, pocetMatematickejOperacie = 0, h; //nainicializujem potrebné premenné + const int DLZKA_PRIKLADU = strlen(priklad); //dĺžka príkladu bude konštantná + + for (h = 0; h < DLZKA_PRIKLADU; h++) { //skontrolujem, či sa nájdená matematická operácia a znamienko = nenachádzajú v príklade viackrát + if (priklad[h] == matematickaOperacia) pocetMatematickejOperacie++; //ak sa nachádza niektorí zo znakov v príklade, tak ho započítam do príslušnej premennej + else if (priklad[h] == '=') pocetRovnaSa++; + } + + if (pocetMatematickejOperacie != 1) return EXIT_FAILURE; //ak sa daná matematická operácia, alebo znamienko = nachádzajú v príklade viackrát, tak kontrolu ukončím, pretože príklad nie je zapísaný v požadovanom formáte + if (pocetRovnaSa != 1) return EXIT_FAILURE; + + char matematickeOperacie[] = "+-*/"; //vytvorím zoznam matematických operácií + const int POCET_MATEMATICKYCH_OPERACII = strlen(matematickeOperacie); //a zistím ich počet + + for (h = 0; h < POCET_MATEMATICKYCH_OPERACII; h++) { //skontrolujem, či sa okrem prvotne nájdenej matematickej operácie v príklade nenachádzajú aj iné matematické operácie + if (matematickeOperacie[h] == matematickaOperacia) continue; //ak sa hľadaná matematická operácia zhoduje s prvotne nájdenou matematickou operáciou, tak jej hľadanie preskočím, pretože kontrola tejto operácie už prebehla + if (strchr(priklad, matematickeOperacie[h]) != NULL) return EXIT_FAILURE; //ak nájdem v príklade inú matematickú operáciu než tú, ktorú som našiel prvotne, tak kontrolu ukončím, pretože príklad nie je zapísaný v požadovanom formáte + } + + return EXIT_SUCCESS; //ak kontrola prebehla úspešne, tak vrátim stavové hlásenie EXIT_SUCCESS +} + +float vypocitaj(float cislo1, float cislo2, char matematickaOperacia) { //funkcia spočíta dve čísla podľa zvolenej matematickej operácie + switch (matematickaOperacia) { //switch zvolí podľa zadanej matematickej operácie + case '+': return cislo1 + cislo2; + break; + + case '-': return cislo1 - cislo2; + break; + + case '*': return cislo1 * cislo2; + break; + + case '/': return cislo1 / cislo2; + break; + + default: return EXIT_FAILURE; //ošetrenie pre prípad, že používateľ nezadá ako parameter matematickú operáciu + } +} + +void mazanie_znakov_v_retazci(char* vstup1, char nepotrebnyZnak) { //funkcia vyhľadá v reťazci hľadaný znak a vymaže ho + int l, m, dlzkaRetazca = strlen(vstup1); //nainicializujem si potrebné premenné + + for (l = 0; l < dlzkaRetazca; l++) { //prejdem celý reťazec znak po znaku + if (vstup1[l] == nepotrebnyZnak) { //ak nájdem v reťazci znak, ktorý má byť odstránený + for (m = l; m < dlzkaRetazca; m++) vstup1[m] = vstup1[m + 1]; //tak začnem posúvať o 1 miesto naspäť reťazec od aktuálnej pozície + dlzkaRetazca--; //skrátim ho odstránený znak + l--; //nastavím presúvač na pôvodnú pozíciu v rámci reťazca (cyklu) + } + } +}