Compare commits

...

7 Commits

Author SHA1 Message Date
Tomáš Kléger
3a1e87fa24 ex-03: Added solution for rgb converter 2025-10-07 09:39:43 +02:00
Tomáš Kléger
d5710a0b14 ex-03: Add test data 2025-10-07 09:37:55 +02:00
Tomáš Kléger
f287f0952e ex-03: Added assignment detail 2025-10-07 09:37:51 +02:00
Tomáš Kléger
6f61da04ff hw-00: Free buffer 2025-10-07 09:34:16 +02:00
Tomáš Kléger
a46cabebdf hw-00: Fix bad pointer comparison 2025-10-07 09:34:14 +02:00
Tomáš Kléger
81310b9d79 hw-00: Comment code 2025-10-07 09:34:11 +02:00
Tomáš Kléger
60427b7841 hw-00: Use getline and strtol instead to account for special cases 2025-10-07 09:33:55 +02:00
27 changed files with 244 additions and 4 deletions

87
exercise-03-rgb/README.md Normal file
View File

@ -0,0 +1,87 @@
Úkolem je vytvořit program, který převede barvu z RGB zápisu do hexadecimálního formátu.
Na vstupu dostanete definici barvy v podobě rgb ( x, y, z ). x, y a z jsou celá čísla v intervalu od 0 do 255 včetně a reprezentují barevnou složku. Cílem je převést tento formát na formát začínající znakem # a následně bez mezer pro každou barevnou složku hexadecimální zápis na dvě pozice například pro hodnotu 12 vypíšete dvě hodnoty 0C. Formát vstupu a výstupu je vidět níže na ukázce práce programu.
Pokud je vstup neplatný, program to musí detekovat a zobrazit chybové hlášení. Chybové hlášení zobrazujte na standardní výstup (ne na chybový výstup). Za chybu považujte:
- vstup neobsahuje řetězec rgb,
- chybějící čárka nebo závorka,
- chybějící barevná složka,
- barevná složka není validní číslo,
- barevná složka není v rozmezí 0 až 255.
**Ukázky běhu programu:**
```
Zadejte barvu v RGB formatu:
rgb ( 255, 0, 0 )
#FF0000
```
---
```
Zadejte barvu v RGB formatu:
rgb ( 0 , 255 , 0 )
#00FF00
```
---
```
Zadejte barvu v RGB formatu:
rgb(0,0,255)
#0000FF
```
---
```
Zadejte barvu v RGB formatu:
rgb ( 127, 127, 0 )
#7F7F00
```
---
```
Zadejte barvu v RGB formatu:
hsl ( 0, 127, 0 )
Nespravny vstup.
```
---
```
Zadejte barvu v RGB formatu:
rgb ( 255, 0 )
Nespravny vstup.
```
---
```
Zadejte barvu v RGB formatu:
rgb ( 1000, 127, 0 )
Nespravny vstup.
```
---
```
Zadejte barvu v RGB formatu:
RGB ( 100, 200, 0 )
Nespravny vstup.
```
---
**Poznámky:**
- Ukázkové běhy zachycují očekávané výpisy Vašeho programu (tučné písmo) a vstupy zadané uživatelem (základní písmo). Zvýraznění tučným písmem je použité pouze zde na stránce zadání, aby byl výpis lépe čitelný. Váš program má za úkol zobrazit text bez zvýrazňování (bez HTML markupu).
- Znak odřádkování je i za poslední řádkou výstupu (i za případným chybovým hlášením).
- Pro načítání vstupu se hodí funkce scanf. Pomocí funkce scanf lze i snadno kontrolovat přítomnost čárek, závorek a řetězce rgb.
- Nepokoušejte se načíst řetězec rgb do paměti a pak jej kontrolovat. Práce s řetězci je v C komplikovaná a náchylná k chybám. V této úloze to navíc není potřeba, kontrolu zvládne funkce scanf.
- Na výstupu zobrazte hexadecimální číslo s velkými písmeny. Použijte odpovídající formát pro funkci printf.
- Při programování si dejte pozor na přesnou podobu výpisů. Výstup Vašeho programu kontroluje stroj, který požaduje přesnou shodu výstupů Vašeho programu s výstupy referenčními. Za chybu je považováno, pokud se výpis liší. I chybějící nebo přebývající mezera/odřádkování je považováno za chybu. Abyste tyto problémy rychle vyloučili, použijte přiložený archiv se sadou vstupních a očekávaných výstupních dat. Podívejte se na videotutoriál (**Courses -> Video tutoriály**), jak testovací data použít a jak testování zautomatizovat.

90
exercise-03-rgb/main.c Normal file
View File

@ -0,0 +1,90 @@
#include <ctype.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <stdbool.h>
#ifdef __PROGTEST__
#define debug(...) ((void)0)
#else
#define debug(fmt, ...) fprintf(stdout, "[DEBUG %s:%d %s()] " fmt "\n", __FILE__, __LINE__, __func__, ##__VA_ARGS__)
#endif
bool is_numeric(const char* str) {
if(*str == '\0') return false;
for(;*str; str++) {
if(!isdigit(*str))
return false;
}
return true;
}
int invalid_input() {
printf("Nespravny vstup.\n");
return EXIT_FAILURE;
}
int main() {
char* input = NULL;
size_t len;
int rgb[3];
printf("Zadejte barvu v RGB formatu:\n");
ssize_t chars_read = getline(&input, &len, stdin);
if(chars_read == -1) {
printf("Failed to read from stdin\n");
return EXIT_FAILURE;
}
char* dst = input;
for(char * src = input; *src; src++) {
if(!isspace(*src)) {
*dst++ = *src;
}
}
*dst = '\0';
int trimmed_len = strlen(input);
if(strncmp(input, "rgb(", 4) != 0 || input[trimmed_len - 1] != ')') {
debug("%s not in rgb(xxx) format", input);
return invalid_input();
}
input[trimmed_len - 1] = '\0';
char* slice = input + 4;
char* token = strtok(slice, ",");
for(int i = 0; i < 3; i++) {
if(token == NULL) {
debug("Too few numbers");
return invalid_input();
}
if(!is_numeric(token)) {
debug("%s is not a number", token);
return invalid_input();
}
int parsed = atoi(token);
if(parsed < 0 || parsed > 255) {
debug("%d out of RGB range", parsed);
return invalid_input();
}
rgb[i] = parsed;
token = strtok(NULL, ",");
}
if(token != NULL) {
debug("Too many numbers");
return invalid_input();
}
printf("#%02X%02X%02X\n", rgb[0], rgb[1], rgb[2]);
return EXIT_SUCCESS;
}

View File

@ -0,0 +1 @@
rgb ( 255, 0, 0 )

View File

@ -0,0 +1,2 @@
Zadejte barvu v RGB formatu:
#FF0000

View File

@ -0,0 +1,2 @@
Zadejte barvu v RGB formatu:
#FF0000

View File

@ -0,0 +1 @@
rgb ( 0 , 255 , 0 )

View File

@ -0,0 +1,2 @@
Zadejte barvu v RGB formatu:
#00FF00

View File

@ -0,0 +1,2 @@
Zadejte barvu v RGB formatu:
#00FF00

View File

@ -0,0 +1 @@
rgb(0,0,255)

View File

@ -0,0 +1,2 @@
Zadejte barvu v RGB formatu:
#0000FF

View File

@ -0,0 +1,2 @@
Zadejte barvu v RGB formatu:
#0000FF

View File

@ -0,0 +1 @@
rgb ( 127, 127, 0 )

View File

@ -0,0 +1,2 @@
Zadejte barvu v RGB formatu:
#7F7F00

View File

@ -0,0 +1,2 @@
Zadejte barvu v RGB formatu:
#7F7F00

View File

@ -0,0 +1 @@
hsl ( 0, 127, 0 )

View File

@ -0,0 +1,2 @@
Zadejte barvu v RGB formatu:
Nespravny vstup.

View File

@ -0,0 +1,2 @@
Zadejte barvu v RGB formatu:
Nespravny vstup.

View File

@ -0,0 +1 @@
rgb ( 255, 0 )

View File

@ -0,0 +1,2 @@
Zadejte barvu v RGB formatu:
Nespravny vstup.

View File

@ -0,0 +1,2 @@
Zadejte barvu v RGB formatu:
Nespravny vstup.

View File

@ -0,0 +1 @@
rgb ( 1000, 127, 0 )

View File

@ -0,0 +1,2 @@
Zadejte barvu v RGB formatu:
Nespravny vstup.

View File

@ -0,0 +1,2 @@
Zadejte barvu v RGB formatu:
Nespravny vstup.

View File

@ -0,0 +1 @@
RGB ( 100, 200, 0 )

View File

@ -0,0 +1,2 @@
Zadejte barvu v RGB formatu:
Nespravny vstup.

View File

@ -0,0 +1,2 @@
Zadejte barvu v RGB formatu:
Nespravny vstup.

View File

@ -1,11 +1,14 @@
#include <errno.h>
#include <stdio.h> #include <stdio.h>
#include <stdlib.h> #include <stdlib.h>
const char * PROMPT = "ml' nob:"; const char * PROMPT = "ml' nob:";
const char * INPUT_OKAY = "Qapla'"; const char * INPUT_OKAY = "Qapla'";
const char * OUT_OF_RANGE = "Qih mi'"; const char * OUT_OF_RANGE = "Qih mi'";
const char * NOT_A_NUMBER = "Neh mi'"; const char * NOT_A_NUMBER = "Neh mi'";
const char * INVALID_NUMBER = "bIjatlh 'e' yImev";
const char * QUOTES[9] = { const char * QUOTES[9] = {
"noH QapmeH wo' Qaw'lu'chugh yay chavbe'lu' 'ej wo' choqmeH may' DoHlu'chugh lujbe'lu'.", "noH QapmeH wo' Qaw'lu'chugh yay chavbe'lu' 'ej wo' choqmeH may' DoHlu'chugh lujbe'lu'.",
@ -20,23 +23,43 @@ const char * QUOTES[9] = {
}; };
int main() { int main() {
int input = 0; char *buf = NULL;
size_t len = 0;
char* end;
printf("%s\n", PROMPT); printf("%s\n", PROMPT);
int result = scanf("%d", &input);
if(result != 1) { // Use getline for dynamic allocation
ssize_t chars_read = getline(&buf, &len, stdin);
errno = 0;
long input = strtol(buf, &end, 10);
// Check whether a range error occured or
// No characters were read by getline
// or check that strtol didnt move a single char
if(errno == ERANGE || chars_read == -1 || end == buf) {
printf("%s\n", NOT_A_NUMBER); printf("%s\n", NOT_A_NUMBER);
return EXIT_FAILURE; return EXIT_FAILURE;
} }
// getline always adds the \n to the result string
// If the ending char by strtol is not that newline
// It means the string is not a whole number
// (e.g. 12abc, 1.23)
if(*end != '\n') {
printf("%s\n", INVALID_NUMBER);
return EXIT_FAILURE;
}
if(input < 0 || input > 8) { if(input < 0 || input > 8) {
printf("%s %d\n", OUT_OF_RANGE, input); printf("%s %ld\n", OUT_OF_RANGE, input);
return EXIT_FAILURE; return EXIT_FAILURE;
} }
printf("%s\n", INPUT_OKAY); printf("%s\n", INPUT_OKAY);
printf("%s\n", QUOTES[input]); printf("%s\n", QUOTES[input]);
free(buf);
return EXIT_SUCCESS; return EXIT_SUCCESS;
} }