Prostudujte si přednášku z jazyka C na stránce http://efis.tul.cz/~dana.nejedlova/ v odstavci "Programování I a II" od smínku "Řetězce" do snímku "Další standardní funkce pro práci s řetězci". Vyzkoušejte si všechny programy na snímcích, které si máte prostudovat, a následující programy obsahující funkce pro načítání čísel, které můžete potřebovat do vašich projektů. První program využívá ke čtení čísle funkci scanf(), která má tu nevýhodu, že nepozná, že syntakticky správně zadávané číslo přetéká svůj datový typ. Vyzkoušejte například zadat celé číslo 5555555555555555555555555555555555555 nebo reálné číslo 1e100000000000000000000000. #include #define MIN 0 #define MAX 12 #define KONEC 0 double precti_cislo(char *prompt) { /* Funkce je stejna jako v souboru 11.txt s tim rozdilem, ze ma parametr s vyzvou uzivateli. */ double cislo; printf("%s", prompt); while (scanf("%lf", &cislo) != 1) { printf("Nezadali jste cislo.\n"); while (getchar() != '\n') ; printf("%s", prompt); } while (getchar() != '\n') ; return cislo; } int precti_cele_cislo(char *prompt, int *cislo) { /* Funkce dostava nacitane cislo jako parametr odkazem a zaroven vraci jeho vyslednou hodnotu. */ printf("%s", prompt); while (scanf("%d", cislo) != 1) { /* Zde opravdu nema byt &cislo ale cislo, protoze argument cislo je jiz pointer. */ printf("Nezadali jste cele cislo.\n"); while (getchar() != '\n') ; printf("%s", prompt); } while (getchar() != '\n') ; return *cislo; } int zadej_cele_cislo_v_intervalu(char *format, int min, int max) { /* Porovnejte s funkci zadej_cislo_v_intervalu() v souboru 11.txt. */ int cislo; printf(format, min, max); while (precti_cele_cislo(": ", &cislo) < min || cislo > max) { printf("Zadali jste cislo mimo inteval od %d do %d.\n", min, max); printf(format, min, max); } return cislo; } int faktorial(int x) { int i, vysledek; for (i = 1, vysledek = 1; i <= x; i++) vysledek *= i; return vysledek; } int main(void) { int volba, delenec, delitel, podil, cislo; double cislo1, cislo2; do { printf("Zadejte\n"); printf("%d pro ukonceni programu,\n", KONEC); printf("1 pro scitani,\n"); printf("2 pro nasobeni,\n"); printf("3 pro vypocet faktorialu,\n"); printf("4 pro zjisteni delitelnosti dvou celych cisel.\n"); precti_cele_cislo("Zadej svoji volbu: ", &volba); switch (volba) { case KONEC: printf("Konec programu."); break; case 1: printf("Scitani\n"); cislo1 = precti_cislo("Zadej 1. scitanec: "); cislo2 = precti_cislo("Zadej 2. scitanec: "); printf("%f + %f = %f\n", cislo1, cislo2, cislo1 + cislo2); break; case 2: printf("Nasobeni\n"); cislo1 = precti_cislo("Zadej 1. cinitel: "); cislo2 = precti_cislo("Zadej 2. cinitel: "); printf("%f * %f = %f\n", cislo1, cislo2, cislo1 * cislo2); break; case 3: printf("Faktorial\n"); cislo = zadej_cele_cislo_v_intervalu("Zadej argument pro faktorial v intervalu od %d do %d", MIN, MAX); printf("Faktorial cisla %d je %d.\n", cislo, faktorial(cislo)); break; case 4: printf("Delitelnost\n"); /* Kombinace operatoru carky a ternarniho operatoru */ podil = (precti_cele_cislo("Zadej delenec: ", &delenec), precti_cele_cislo("Zadej delitel: ", &delitel) != 0) ? delenec / delitel : printf("Delitel nesmi byt nulovy!\n"); if (podil * delitel == delenec){ /* Kdyz se zada delenec i delitel nulovy, tak vyjde podil jako delka retezce "Delitel nesmi byt nulovy!\n", protoze funkce printf() vraci pocet vytisklych znaku. */ printf("Cislo %d je beze zbytku delitelne cislem %d. Vysledek deleni je %d.\n", delenec, delitel, podil); } else { if (delitel != 0) { printf("%d = %d * %d + %d.\n", delenec, delitel, podil, delenec % delitel); } } break; default: printf("Neznama volba.\n"); break; } } while (volba != KONEC); return 0; } Druhý program nejdříve čísla načte jako řetězec a potom je zpracuje na číslo funkcemi strtod() nebo strtol(), které v případě, že zadané číslo přetéká svůj datový typ, nastaví proměnnou errno na nenulovou hodnotu. #include #include #include #include #include #include #define MIN 0 #define MAX 12 #define KONEC 0 #define MAX_DELKA_RETEZCE 1024 void precti_retezec_a_vyprazdni_buffer(char *s) { int delka; fgets(s, MAX_DELKA_RETEZCE, stdin); delka = strlen(s) - 1; if (s[delka] == '\n') s[delka] = '\0'; else while (getchar() != '\n') ; } bool preved_retezec_na_double(double *cislo) { char cislo_string[MAX_DELKA_RETEZCE]; char *odpad; bool uspech = true; errno = 0; precti_retezec_a_vyprazdni_buffer(cislo_string); *cislo = strtod(cislo_string, &odpad); if (errno != 0 || cislo_string == odpad) { printf("Zadali jste neplatne cislo %s!\n%s\n", cislo_string, sys_errlist[errno]); uspech = false; } if (*odpad != '\0') { printf("Zahozeno \"%s\"!\n", odpad); } return uspech; } bool preved_retezec_na_int(int *cislo) { char cislo_string[MAX_DELKA_RETEZCE]; char *odpad; bool dlouhe_cislo, uspech = true; long cislo_long; errno = 0; precti_retezec_a_vyprazdni_buffer(cislo_string); cislo_long = strtol(cislo_string, &odpad, 10); dlouhe_cislo = cislo_long > INT_MAX || cislo_long < INT_MIN; if (errno != 0 || dlouhe_cislo || cislo_string == odpad) { printf("Zadali jste neplatne cislo %s!\n%s\n", cislo_string, sys_errlist[errno]); uspech = false; } else { *cislo = (int)cislo_long; } if (*odpad != '\0') { printf("Zahozeno \"%s\"!\n", odpad); } return uspech; } double precti_cislo(char *prompt) { double cislo; printf("%s", prompt); while (preved_retezec_na_double(&cislo) == false) { printf("%s", prompt); } return cislo; } int precti_cele_cislo(char *prompt) { int cislo; printf("%s", prompt); while (preved_retezec_na_int(&cislo) == false) { printf("%s", prompt); } return cislo; } int zadej_cele_cislo_v_intervalu(char *format, int min, int max) { int cislo; printf(format, min, max); while ((cislo = precti_cele_cislo(": ")) < min || cislo > max) { printf("Zadali jste cislo mimo inteval od %d do %d.\n", min, max); printf(format, min, max); } return cislo; } int faktorial(int x) { int i, vysledek = 1; /* vysledek inicializujeme hodnotu faktorialu pro argument 0. */ for (i = x; i; i--) /* i s hodnotou 0 je false a ukonci tedy cyklus. */ vysledek *= i; /* Provede se jen pro argument x > 0, jinak zustava vysledek = 1. */ return vysledek; } int main(void) { int volba, delenec, delitel, podil, cislo; double cislo1, cislo2; do { printf("Zadejte\n"); printf("%d pro ukonceni programu,\n", KONEC); printf("1 pro scitani,\n"); printf("2 pro nasobeni,\n"); printf("3 pro vypocet faktorialu,\n"); printf("4 pro zjisteni delitelnosti dvou celych cisel.\n"); volba = precti_cele_cislo("Zadej svoji volbu: "); switch (volba) { case KONEC: printf("Konec programu."); break; case 1: printf("Scitani\n"); cislo1 = precti_cislo("Zadej 1. scitanec: "); cislo2 = precti_cislo("Zadej 2. scitanec: "); printf("%f + %f = %f\n", cislo1, cislo2, cislo1 + cislo2); break; case 2: printf("Nasobeni\n"); cislo1 = precti_cislo("Zadej 1. cinitel: "); cislo2 = precti_cislo("Zadej 2. cinitel: "); printf("%f * %f = %f\n", cislo1, cislo2, cislo1 * cislo2); break; case 3: printf("Faktorial\n"); cislo = zadej_cele_cislo_v_intervalu("Zadej argument pro faktorial v intervalu od %d do %d", MIN, MAX); printf("Faktorial cisla %d je %d.\n", cislo, faktorial(cislo)); break; case 4: printf("Delitelnost\n"); delenec = precti_cele_cislo("Zadej delenec: "); delitel = precti_cele_cislo("Zadej delitel: "); if (delitel != 0) { podil = delenec / delitel; if (podil * delitel == delenec ) { printf("Cislo %d je beze zbytku delitelne cislem %d. Vysledek deleni je %d.\n", delenec, delitel, podil); } else { printf("%d = %d * %d + %d.\n", delenec, delitel, podil, delenec % delitel); } } else { printf("Delitel nesmi byt nulovy!\n"); } break; default: printf("Neznama volba.\n"); break; } } while (volba != KONEC); return 0; }