Обновить du3/program.c

This commit is contained in:
Bohdana Marchenko 2025-03-12 17:38:46 +00:00
parent 1071f99ece
commit fa09da2a6d

View File

@ -4,22 +4,22 @@
#include <math.h> #include <math.h>
#include <ctype.h> #include <ctype.h>
#define EPSILON 0.001 // Tolerancia pre porovnanie reálnych čísel: ak rozdiel dvoch čísel je menší alebo rovný EPSILON, považujeme ich za rovnaké. #define EPSILON 0.001 // Tolerancia pre porovnanie reálnych čísel: ak je rozdiel dvoch čísel menší alebo rovný EPSILON, považujeme ich za rovnaké.
/* /*
* Funkcia trim_newline * Funkcia trim_newline
* -------------------- * --------------------
* Odstraňuje znak nového riadku ('\n') zo zadaného reťazca, ak je prítomný. * Odstraňuje znak nového riadku ('\n') zo zadaného reťazca, ak je prítomný.
* Táto funkcia je užitočná, keď načítavame riadky pomocou fgets, * Pri načítavaní riadkov pomocou fgets sa totiž často na konci reťazca nachádza '\n',
* pretože fgets zachytáva aj znak nového riadku, ktorý by mohol narušiť parsovanie. * ktorý by mohol ovplyvniť ďalšie spracovanie.
* *
* Parametre: * Parametre:
* - line: reťazec, z ktorého chceme odstrániť koncový znak nového riadku. * - line: Reťazec, z ktorého sa odstrániť koncový znak nového riadku.
* *
* Príklad použitia: * Príklad použitia:
* char buffer[256]; * char buffer[256];
* fgets(buffer, sizeof(buffer), stdin); * fgets(buffer, sizeof(buffer), stdin);
* trim_newline(buffer); // Odstráni '\n' na konci, ak existuje. * trim_newline(buffer); // Odstráni '\n' z konca reťazca, ak existuje.
*/ */
void trim_newline(char *line) { void trim_newline(char *line) {
size_t len = strlen(line); size_t len = strlen(line);
@ -35,10 +35,10 @@ void trim_newline(char *line) {
* a vráti ukazovateľ na prvý znak, ktorý nie je whitespace. * a vráti ukazovateľ na prvý znak, ktorý nie je whitespace.
* *
* Parametre: * Parametre:
* - str: reťazec, v ktorom chceme preskočiť medzery. * - str: Reťazec, v ktorom chceme preskočiť medzery.
* *
* Návratová hodnota: * Návratová hodnota:
* - Ukazovateľ na prvý znak, ktorý nie je medzera. * - Ukazovateľ na prvý znak, ktorý nie je whitespace.
*/ */
char* skip_spaces(char *str) { char* skip_spaces(char *str) {
while(*str && isspace((unsigned char)*str)) { while(*str && isspace((unsigned char)*str)) {
@ -177,7 +177,7 @@ float calculate(float num1, char op, float num2, int *error) {
* *
* Postup: * Postup:
* 1. Skopíruje vstupný riadok do lokálneho bufferu a odstráni prípadný koncový znak nového riadku. * 1. Skopíruje vstupný riadok do lokálneho bufferu a odstráni prípadný koncový znak nového riadku.
* 2. Ak riadok obsahuje iba medzery, nastaví output na "KONIEC". * 2. Predpokladá sa, že riadok nie je prázdny (kontrola prázdnoty sa vykoná v main).
* 3. Pokúsi sa rozparsovať riadok na jednotlivé časti: prvé číslo, operátor, druhé číslo a výsledok. * 3. Pokúsi sa rozparsovať riadok na jednotlivé časti: prvé číslo, operátor, druhé číslo a výsledok.
* 4. Ak parsovanie zlyhá, nastaví output na "CHYBA". * 4. Ak parsovanie zlyhá, nastaví output na "CHYBA".
* 5. Ak ide o delenie nulou, tiež nastaví output na "CHYBA". * 5. Ak ide o delenie nulou, tiež nastaví output na "CHYBA".
@ -187,26 +187,20 @@ float calculate(float num1, char op, float num2, int *error) {
* *
* Parametre: * Parametre:
* - line: Vstupný riadok (napr. "10.0 / 2.0 = 5.0"). * - line: Vstupný riadok (napr. "10.0 / 2.0 = 5.0").
* - output: Buffer, do ktorého sa uloží výsledný reťazec ("OK", "ZLE", "CHYBA" alebo "KONIEC"). * - output: Buffer, do ktorého sa uloží výsledný reťazec ("OK", "ZLE" alebo "CHYBA").
* - output_size: Veľkosť bufferu output. * - output_size: Veľkosť bufferu output.
* *
* Príklad vstupu a výstupu: * Príklad vstupu a výstupu:
* Vstup: "1+2=3" * Vstup: "1 + 1 = 2"
* Výstup: "OK" * Výstup: "OK"
*/ */
void process_line(const char *line, char *output, size_t output_size) { void process_line(const char *line, char *output, size_t output_size) {
char buffer[256]; char buffer[256];
// Skopírujeme vstupný riadok do lokálneho bufferu
strncpy(buffer, line, 255); strncpy(buffer, line, 255);
buffer[255] = '\0'; // Zabezpečíme, že buffer je správne zakončený '\0' buffer[255] = '\0'; // Zabezpečíme, že buffer je správne zakončený '\0'
trim_newline(buffer); trim_newline(buffer);
// Ak riadok obsahuje iba medzery, nastavíme výstup na "KONIEC"
char *tmp = skip_spaces(buffer);
if (*tmp == '\0') {
snprintf(output, output_size, "KONIEC");
return;
}
float num1, num2, givenResult; float num1, num2, givenResult;
char op; char op;
// Pokúsime sa rozparsovať matematický príklad // Pokúsime sa rozparsovať matematický príklad
@ -228,8 +222,8 @@ void process_line(const char *line, char *output, size_t output_size) {
return; return;
} }
// Porovnáme vypočítaný výsledok so zadaným výsledkom // Porovnáme vypočítaný výsledok so zadaným výsledkom.
// Ak je absolútny rozdiel menší alebo rovný EPSILON, výsledok považujeme za správny // Ak je absolútny rozdiel menší alebo rovný EPSILON, považujeme príklad za správny.
if (fabs(calculatedResult - givenResult) <= EPSILON) { if (fabs(calculatedResult - givenResult) <= EPSILON) {
snprintf(output, output_size, "OK"); snprintf(output, output_size, "OK");
} else { } else {
@ -240,7 +234,7 @@ void process_line(const char *line, char *output, size_t output_size) {
/* /*
* Hlavná funkcia programu. * Hlavná funkcia programu.
* ------------------------- * -------------------------
* Tento program načíta riadky zo štandardného vstupu. Každý riadok obsahuje matematický príklad vo formáte: * Program načíta riadky zo štandardného vstupu. Každý riadok obsahuje matematický príklad vo formáte:
* *
* ČÍSLO OPERÁCIA ČÍSLO = VÝSLEDOK * ČÍSLO OPERÁCIA ČÍSLO = VÝSLEDOK
* *
@ -248,17 +242,17 @@ void process_line(const char *line, char *output, size_t output_size) {
* 10.0 / 2.0 = 5.0 * 10.0 / 2.0 = 5.0
* 1+2=3 * 1+2=3
* 3.333+4.667=8.0 * 3.333+4.667=8.0
* [prázdny riadok] // Po načítaní prázdneho riadku program vypíše "KONIEC" a ukončí sa.
* *
* Pre každý riadok program vypíše na štandardný výstup: * Program pre každý neprázdny riadok overí správnosť zápisu a výsledku a na štandardný výstup
* OK - ak je výsledok správny * vypíše "OK", "ZLE" alebo "CHYBA".
* ZLE - ak je výsledok nesprávny
* CHYBA - ak je riadok zle zapísaný alebo nastala chyba (napr. delenie nulou)
* KONIEC - ak je riadok prázdny
* *
* Ako spustiť program: * Poznámka: Ak sa načíta prázdny riadok (obsahuje iba medzery), program ho ignoruje a ukončí sa.
* - Kompilujte: gcc program.c -o program -lm *
* - Spustite: ./program * Ako skompilovať:
* gcc program.c -o program -lm
*
* Ako spustiť:
* ./program
*/ */
int main(int argc, char *argv[]) { int main(int argc, char *argv[]) {
char buffer[256]; char buffer[256];
@ -267,14 +261,13 @@ int main(int argc, char *argv[]) {
// Načítavame riadky zo štandardného vstupu (napr. z konzoly alebo súboru) // Načítavame riadky zo štandardného vstupu (napr. z konzoly alebo súboru)
while (fgets(buffer, sizeof(buffer), stdin) != NULL) { while (fgets(buffer, sizeof(buffer), stdin) != NULL) {
trim_newline(buffer); trim_newline(buffer);
process_line(buffer, output, sizeof(output)); // Ak je riadok prázdny (iba medzery), ukončíme cyklus a teda program
printf("%s\n", output); if (*skip_spaces(buffer) == '\0') {
// Ak je vstup prázdny (obsahuje iba medzery), ukončíme program
char *tmp = skip_spaces(buffer);
if (*tmp == '\0') {
break; break;
} }
process_line(buffer, output, sizeof(output));
printf("%s\n", output);
} }
return 0; return 0;
} }