Keyboard shortcuts

Press or to navigate between chapters

Press S or / to search in the book

Press ? to show this help

Press Esc to hide this help

První bonusový úkol

Odevzdání

Úkol odevzdejte mailem (adresu najdete na webu katedry), s předmětem ZP2 - Bonusový úkol 1, jako přílohu soubor se zdrojovým kódem (a nic dalšího). Odevzdávejte nejpozději 2. 3. ve 23:59.

Body

Za úkol lze získat 4 body.

Zadání

Uvažujme následující strukturu pro řetězec. Položka data není zakončená 0, místo toho si pamatuje svoji délku v položce len.

typedef struct 
{
	char*  data;
	size_t len;
} String;

Prázdný řetězec má obě položky nastaveny na 0.

Řětězce budeme vytvářet pomocí funkce (není nutno se zabývat jejím tělem, funkci stačí skopírovat do zdrojáku).

String clone_from_cstring(char *cstring) 
{
	String ret = {0};
	ret.len  = strlen(cstring);
	if (ret.len == 0) 
	{
		ret.data = 0;
	}
	else 
	{
		ret.data = malloc(ret.len);
		assert(ret.data);
		memcpy(ret.data, cstring, ret.len);
	}
	return ret;
}

Naprogramujte následující funkce

void print_string(String str);

Funkce vytiskne řetězec str.

String get_prefix(String str, char delimiter, String* remainder);

Funkce vrátí prefix řetězce str až do prvního výskytu znaku delimiter. Ten ovšem do výsledku nepatří. Do argumentu remainder zapíše zbytek řetězce, s tím že delimiter na začátku vynechá.

//
// Příklad použítí funkce get_prefix
//
String a = clone_from_cstring("xx-yy");
String b = clone_from_cstring("xx--zz");
String c = clone_from_cstring("-xxxx");
String d = clone_from_cstring("xxx");
String e = clone_from_cstring("");

String rem;
String res;

//
// následující vytiskne "xx" a "yy" 
//
res = get_prefix(a, '-', &rem);
print_string(res);
print_string(rem);

//
// následující vytiskne "xx" a "-zz" 
//
res = get_prefix(b, '-', &rem);
print_string(res);
print_string(rem);

//
// následující vytiskne "" a "xxxx" 
//
res = get_prefix(c, '-', &rem);
print_string(res);
print_string(rem);

//
// následující vytiskne "xxx" a "" 
//
res = get_prefix(d, '-', &rem);
print_string(res);
print_string(rem);

//
// následující vytiskne "" a "" 
//
res = get_prefix(e, '-', &rem);
print_string(res);
print_string(rem);
int string_to_long(String s, long* result);

Funkce převede číslo zapsané jako řetězec na long. Číslo může být záporné. Pokud je s prázdný, je výsledkem převodu 0. Výsledné číslo je zapsáno do argumentu result. Funkce vrací 1, pokud se povedlo číslo z řetězce převést, jinak vrací 0.

int compute_the_thing(String s, long* result);

s je text, který obsahuje na každém řádku mezerami oddělená celá čísla. Funkce vrací číslo, které dostane následovně: čísla v každém řádku sečte; výsledek dostane tak, že sečte součty sudých řádků a od toho odečte součty lichých řádků. Výsledek zapíše do result. Pokud se část řetězce nepovede převést na číslo, vrátí funkce 0, jinak vrací 1. Například, pokud je s

2 2
2 2 2
-2 3

jsou součty řádků postupně 4, 6, 1 a výsledek je -4 + 6 -1 = 1 a funkce vrátí 1.

int res = 0;
int ok  = 0;

//
//  Následující vytiskne 1, 1
//
String s = clone_from_cstring("2 2\n2 2 2\n-2 3");
ok = compute_the_thing(s, &res);
printf("%i %i\n", res, ok);


//
// Následující vytiskne -3, 0
//
res = -3;
String t = clone_from_cstring("2 2\nx y\n");
ok = compute_the_thing(t, &res);
printf("%i %i\n", res, ok);

Omezení

Je zakázáno používat funkce pro manipulaci s řetězci, které jsou ve standardní knihovně. Tj. úkol nelze řešit způsobem: nejdříve převedu String na řetězec v C, potom zavolám knihovní funkci, a nakonec výsledek převedu zpátky na String.