Search
1. úkol se zaměřuje na práci s formátovaným vstupem a výstupem a skládá se ze čtyř malých úloh:
K dispozici máte archiv obsahující Catch testy, které vám zkontrolují vaše řešení, a dva další soubory. Hlavičkový soubor small1.hpp obsahuje deklarace funkcí, které máte implementovat; a zdrojový soubor small1.cpp obsahuje jejich prázdná těla. Archiv se tedy dá po stažení zkompilovat a spustit, ale neprojdou testy.
small1.hpp
small1.cpp
Odevzdávejte soubor .zip, který obsahuje jeden nebo více souborů .cpp, ve kterých jsou implementované funkce z hlavičkových souborů z domácího úkolu. Vámi odevzdané soubory by neměly být schované v podsložce a prosíme vás, abyste neodevzdávali soubory vašeho IDE1).
.zip
.cpp
Žádný ze souborů s testy není třeba odevzdávat.
Catch je framework pro psaní testů pro C++ kód. Základní použití je jednoduché, stačí v nějakém souboru deklarovat makro CATCH_CONFIG_MAIN před includováním hlavičky catch.hpp a v ostatních souborech se již můžou psát testy. Následně stačí zkompilovat zdrojové soubory a spustit výsledný program, čímž se provedou a vypíšou výsledky testů.
Catch
CATCH_CONFIG_MAIN
catch.hpp
V archivu, který máte od nás, najdete catch.hpp, hlavičku s aktuální verzí testovací testovacího frameworku, tests-main.cpp, zdrojový soubor s definicí makra CATCH_CONFIG_MAIN, a tests-small1.cpp, ve kterém jsou testy pro vaši implementaci.
tests-main.cpp
tests-small1.cpp
Všechny odevzdané úkoly jsou kontrolovány za použití Valgrindu. Valgrind je schopen najít spoustu chyb, které se normálně nemusí projevit, a v případě, že nějakou najde, bude vám sražena část bodů z domácího úkolu.
V různých úkolech si můžete ulehčit práci použitím standardních knihoven. V tomto doporučujeme podívat se blíže na hlavičku <iomanip> a samozřejmě na věci, které se probíraly na cvičení (například std::stringstream).
std::stringstream
Pokud kompilujete z příkazové řádky2), pravděpodobně zjitíte, že vám kompilace běží velmi dlouho (5-10s). Protože nejdelší dobu se kompiluje soubor tests-main.cpp, který se nebude měnit, vyplatí se ho zkompilovat do tzv. objektového souboru. Objektové soubory jsou mezikrok mezi implementačními soubory a fungujícím programem.
Pokud spustíte kompilátor s argumentem -c, místo binárky se vám vytvoří objektové soubory. Volání
-c
clang++ -std=c++14 tests-small.cpp tests-main.cpp -c
tests-small.o
tests-main.o
tests-small.cpp
.o
Výsledné volání pro kompilaci tedy bude zhruba takovéto
clang++ -std=c++14 tests-small.o tests-main.o small1.cpp -o small1
Pokud se něco pokazí při kompilaci, C++ je schopno generovat opravdu dlouhé chyby. Ve skutečnosti je z nich obvykle relevantní pouze krátká část, protože výpis má formu kompilačního stacktrace – při kompilaci jaké funkce vznikla chyba a proč byla daná funkce kompilována. To znamená, že při čtení kompilační chyby je potřeba najít první výpis, který je ve vašem kódu, protože právě ten způsobuje danou chybu. Kompilátory dále mají tendenci přidat na konec výpisu chyby informace, o co všechno se pokusili.
Co to znamená, ukážeme na příkladu:
#include <iostream> int main(){ int i; std::cout >> i; std::cout << i; }
std::cin
std::cout
test.cpp:5:15: error: invalid operands to binary expression ('ostream' (aka 'basic_ostream<char>') and 'int') std::cout >> i; ~~~~~~~~~ ^ ~ /usr/bin/../lib/gcc/x86_64-linux-gnu/5.3.1/../../../../include/c++/5.3.1/streambuf:168:9: note: candidate template ignored: could not match 'basic_istream' against 'basic_ostream' operator>>(basic_istream<_CharT2, _Traits2>&, ^ /usr/bin/../lib/gcc/x86_64-linux-gnu/5.3.1/../../../../include/c++/5.3.1/istream:756:5: note: candidate template ignored: could not match 'basic_istream' against 'basic_ostream' operator>>(basic_istream<char, _Traits>& __in, unsigned char& __c) ^ /usr/bin/../lib/gcc/x86_64-linux-gnu/5.3.1/../../../../include/c++/5.3.1/istream:761:5: note: candidate template ignored: could not match 'basic_istream' against 'basic_ostream' operator>>(basic_istream<char, _Traits>& __in, signed char& __c) ^ /usr/bin/../lib/gcc/x86_64-linux-gnu/5.3.1/../../../../include/c++/5.3.1/istream:803:5: note: candidate template ignored: could not match 'basic_istream' against 'basic_ostream' operator>>(basic_istream<char, _Traits>& __in, unsigned char* __s) ^ /usr/bin/../lib/gcc/x86_64-linux-gnu/5.3.1/../../../../include/c++/5.3.1/istream:808:5: note: candidate template ignored: could not match 'basic_istream' against 'basic_ostream' operator>>(basic_istream<char, _Traits>& __in, signed char* __s) ^ /usr/bin/../lib/gcc/x86_64-linux-gnu/5.3.1/../../../../include/c++/5.3.1/bits/istream.tcc:923:5: note: candidate template ignored: could not match 'basic_istream' against 'basic_ostream' operator>>(basic_istream<_CharT, _Traits>& __in, _CharT& __c) ^ /usr/bin/../lib/gcc/x86_64-linux-gnu/5.3.1/../../../../include/c++/5.3.1/bits/istream.tcc:955:5: note: candidate template ignored: could not match 'basic_istream' against 'basic_ostream' operator>>(basic_istream<_CharT, _Traits>& __in, _CharT* __s) ^ 1 error generated.
Hned první řádek výpisu se odkazuje do našeho kódu a zhruba říká, kde je chyba (nemůžeme použít operátor >> na výstupní proud a int), ale výpis obsahuje spoustu dalších řádků, které popisují, co všechno kompilátor zkusil, než došel k tomu, že to je chyba. V tomto případě vyzkoušel různá přetížení operátoru >>, ale zjistil, že žádné z nich nepasuje pro daný výraz.
>>
Pokud vám linkování programu selže s chybou během linkování, pravděpodobně to znamená, že nelinkujete vše, co máte.
main
Catch::
Úkol obsahuje časově náročné testy, které jsou při normálním spuštění vypnuté. Pokud je chcete spustit, musíte zavolat výslednou binárku s argumentem [.long]:
[.long]
small1 [.long]
Silně doporučujeme ho spouštět pouze v optimalizované binárce, tj. kompilovat v Release módu nebo na příkazové řádce s parametrem -O3.
-O3