Jak v C realizovat rčení Margaret Hamilton, že uživatelé chybují a počítače s tím musí počítat.
Základní ošetření pomocí IF a masky příkazu scanf
#include <stdio.h>
#include <stdbool.h> //umozni poutivat logicke funkce
void main()
{
int celeCislo;
do
{
printf("Zadej cele cislo: ");
if (scanf("%d", &celeCislo) == 1)
{
break; //ukonci nekonecny cyklus
}
else
{
printf("Na vstupu neni cislo, opakuj zadani\n");
getchar(); //snaze potvrzovaci enter z bufferu vstupu
}
} while (true);
getchar(); //snaze potvrzovaci enter z bufferu vstupu
printf("Zadane cislo je %d.", celeCislo);
float DesetinnneCislo;
printf("Zadane cislo je %d.", celeCislo);
do
{
printf("\nZadej desetinne cislo: ");
if (scanf("%f", &DesetinnneCislo) == 1)
{
break;
}
else
{
printf("Na vstupu neni cislo, opakuj zadani\n");
getchar();
}
} while (true);
getchar(); //snaze potvrzovaci enter z bufferu vstupu
printf("Zadane cislo je %f.", DesetinnneCislo);
}
Přetypování ze stringu pomocí knihovních funkcí
#include <stdio.h>
#include <ctype.h> //validace datovych typu
#include <stdlib.h>
#include <string.h> //textove retezce
#include <stdbool.h> //datovy typ bool
#define BUFFER_SIZE 4096 //velikost bufferu
bool parse_int(char* string, int* integer)
{
//na vstupu prijme string a vrati true a hdonotu integeru, pokud je stringem cele cislo
//odmaze pripadne mezery a taby kolem cisla
int i = 0; //idex pocatku retezce
while (isspace(string[i])) //dokud je pred prvkem mezera, novy radek nebo tab
{
i++; //nastavi index na zacatek nejake hodnoty
}
int length = strlen(string); //ulozi delku retezce
if (length == i)
{
return false; //reteezec byl prazdny, jen bile znaky
}
char integet_buffer[BUFFER_SIZE];
int integer_chars = 0;
//detekce zaporne hodnoty
if (string[i] == '-')
{
integet_buffer[integer_chars] = '-';
integer_chars++;
i++;
if (!isdigit(string[i])) //validace, zda je dalsi zank cislo
{
return false; //kdyz neni dalsi znak cislo, vracime false
}
}
//nacteni ciselnych hodnot z retezce
while (i < length && !isspace(string[i])) //doku i je mensi nez delka a zaroven nejde o mezeru
{
if (!isdigit(string[i])) //pokud znak neni cislo vrat false
{
return false;
}
//pokud jde o cislo, pridame jej do bufferu
integet_buffer[integer_chars] = string[i];
integer_chars++;
i++;
}
//korektni ukonceni textoveho retezce
integet_buffer[integer_chars] = '\0';
*integer = atoi(integet_buffer); //vlastni konverze z retezce na cislo
return true;
}
bool parse_float(char* string, float* desetinne)
{
//na vstupu prijme string a vrati true a hdonotu float, pokud je stringem cele cislo
//odmaze pripadne mezery a taby kolem cisla
int i = 0; //idex pocatku retezce
while (isspace(string[i])) //dokud je pred prvkem mezera, novy radek nebo tab
{
i++; //nastavi index na zacatek nejake hodnoty
}
int length = strlen(string); //ulozi delku retezce
if (length == i)
{
return false; //reteezec byl prazdny, jen bile znaky
}
char desetinne_buffer[BUFFER_SIZE];
int desetinne_chars = 0;
//detekce zaporne hodnoty
if (string[i] == '-')
{
desetinne_buffer[desetinne_chars] = '-';
desetinne_chars++;
i++;
if (!isdigit(string[i])) //validace, zda je dalsi zank cislo
{
return false; //kdyz neni dalsi znak cislo, vracime false
}
}
//nacteni ciselnych hodnot z retezce
bool carka = false;
while (i < length && !isspace(string[i])) //doku i je mensi nez delka a zaroven nejde o mezeru
{
if((string[i]=='.' || string[i] == ',') && (!carka)) //detekce desetinne carky resp tecky
{
desetinne_buffer[desetinne_chars] = '.'; //pridani desetinne carky
carka = true;
}
else if (!isdigit(string[i])) //pokud znak neni cislo vrat false
{
return false;
}
else
{
//pokud jde o cislo, pridame jej do bufferu
desetinne_buffer[desetinne_chars] = string[i];
}
//posun k dalsimu znaku
desetinne_chars++;
i++;
}
//korektni ukonceni textoveho retezce
desetinne_buffer[desetinne_chars] = '\0';
*desetinne = atof(desetinne_buffer); //vlastni konverze z retezce na cislo
return true;
}
int main()
{
int cislo;
float cislo2;
char buffer[BUFFER_SIZE]; //textove pole pro ulozeni vstupu
bool uspech = true;
do
{
printf("Zadej cele cislo: ");
scanf(" %4096[^\n]s", buffer);; //nacteni z konzole do bufferu
uspech = parse_int(buffer, &cislo); //promenou cislo predavame jako ukazatel v pameti
if (!uspech)
{
printf("Musi byt zadano cele cislo\n");
}
} while (!uspech); //dokud neni spravne nacteno
printf("Zadane cele cislo je %d\n", cislo);
uspech = true;
do
{
printf("Zadej desetinne cislo: ");
scanf(" %4096[^\n]s", buffer);; //nacteni z konzole do bufferu
uspech = parse_float(buffer, &cislo2); //promenou cislo predavame jako ukazatel v pameti
if (!uspech)
{
printf("Musi byt zadano cele cislo\n");
}
} while (!uspech); //dokud neni spravne nacteno
printf("Zadane destinne cislo je %f\n", cislo2);
return 0;
}
Vlastní konverzní funkce využívající dekadický zápis čísel
#include <stdlib.h>
#include <stdio.h>
#include <math.h>
#include <string.h>
#define DELKA 4096
//vyuzit dekatickeho zapisu pro konverzi string na int
void main()
{
char text[DELKA]; //pro přímé zadání vstupu
char cislice[DELKA]; //ocistene cislo
int cislo = 0; //finalni cislice
float desetine = 0.0;
int i = 0, j = 0; //ridici promene
int zaporne = 0; //detekce zaporne hodnoty
printf("Zadej cele cislo: ");
scanf_s("%4096[^\n]s", &text, 4096); //nacteni cisla v podobe textu
getchar();
//odmazani mezer a dalsich bilich znaku pred cislem
for (i = 0; i < DELKA; i++)
{
if (!isspace(text[i]))
{
break;
}
}
if (i < DELKA)
{
if (text[i] == '-') //detekce zaporne hodnoty
{
i++;
zaporne = -1;
}
do
{
if (isdigit(text[i])) //prevedeni ciselnych hodnot do druheho pole (ciste cislo)
{
cislice[j] = text[i];
}
else if (isspace(text[i])) //mezera za cislem => ukonceni prevodu
{
break;
}
else if (text[i] == '\0') //znak konce retezce ukonci prevod
{
cislice[j] = text[i]; //ukonceni retezce cisteho sicla
break;
}else
{
printf("Nejde o ciso"); //vypis chyby
break;
}
//povyseni ridicich promenych
j++;
i++;
} while (i < DELKA);
int mocnina = 0; //hodnota mocniny deseti
//prevod pomoci dekadickeho zapisu disla (mantisa * deset na pozici)
for (int d = strlen(cislice) -1; d >= 0; d--)
{
switch (cislice[d])
{
case '0':
cislo = cislo + 0 * pow(10, mocnina);
break;
case '1':
cislo = cislo + 1 * pow(10, mocnina);
break;
case '2':
cislo = cislo + 2 * pow(10, mocnina);
break;
case '3':
cislo = cislo + 3 * pow(10, mocnina);
break;
case '4':
cislo = cislo + 4 * pow(10, mocnina);
break;
case '5':
cislo = cislo + 5 * pow(10, mocnina);
break;
case '6':
cislo = cislo + 6 * pow(10, mocnina);
break;
case '7':
cislo = cislo + 7 * pow(10, mocnina);
break;
case '8':
cislo = cislo + 8 * pow(10, mocnina);
break;
case '9':
cislo = cislo + 9 * pow(10, mocnina);
break;
default:
break;
}
mocnina++; //povyseni mocniny pro dalsi pozici
}
if (zaporne == -1) //realizace zaporne hodnoty
{
cislo = cislo * (-1);
}
}
//kontolni vypis cisla
printf("\n\nZadane cislo je %d", cislo);
//desetinne cislo
//nulovani ridicich promennych
i = 0;
j = 0;
zaporne = 0;
//nulvani retezcu
for (int i = 0; i < DELKA; i++)
{
text[i] = '\0';
cislice[i] = '\0';
}
i = 0; //opetovne vynulovani
printf("\n\nZadej desetinne cislo: ");
scanf_s("%4096[^\n]s", &text, 4096); //nacteni cisla v podobe textu
//odmazani mezer a dalsich bilich znaku pred cislem
for (i = 0; i < DELKA; i++)
{
if (!isspace(text[i]))
{
break;
}
}
if (i < DELKA) //pokud retezec obsahuje jiny nez bily znak
{
if (text[i] == '-') //detekce zaporne hodnoty
{
i++;
zaporne = -1;
}
do
{
if (isdigit(text[i])) //prevedeni ciselnych hodnot do druheho pole (ciste cislo)
{
cislice[j] = text[i];
}
else if (isspace(text[i])) //mezera za cislem => ukonceni prevodu
{
break;
}
else if (text[i] == '\0') //znak konce retezce ukonci prevod
{
cislice[j] = text[i]; //ukonceni retezce cisteho sicla
break;
}
else if (text[i] == '.' || text[i] == ',') //detekce a prevedeni desetinneho oddelovace
{
cislice[j] = text[i];
}
else
{
printf("Nejde o ciso"); //vypis chyby
break;
}
//povyseni ridicich promenych
j++;
i++;
} while (i < DELKA);
int mocnina = 0; //hodnota mocniny deseti
int tecka = -1; //pozice desetineho oddelovace
for (int k = 0; k < strlen(cislice); k++) //nalezeni pozice desetinneho oddelovace
{
if (cislice[k] == '.' || cislice[k] == ',')
{
tecka = k;
break;
}
}
if (tecka > -1) //jestli je desetinna nalezena
{
//prevod desetinne casti
mocnina = 1; //nastaveni na rad desetin
for (int d = tecka+1; d <strlen(cislice); d++)
{
switch (cislice[d])
{
case '0':
desetine = desetine + 0 * pow(10, (mocnina * (-1))); //hodnota cifry * 10 na -cifru
break;
case '1':
desetine = desetine + 1 * pow(10, (mocnina * (-1)));
break;
case '2':
desetine = desetine + 2 * pow(10, (mocnina * (-1)));
break;
case '3':
desetine = desetine + 3 * pow(10, (mocnina * (-1)));
break;
case '4':
desetine = desetine + 4 * pow(10, (mocnina * (-1)));
break;
case '5':
desetine = desetine + 5 * pow(10, (mocnina * (-1)));
break;
case '6':
desetine = desetine + 6 * pow(10, (mocnina * (-1)));
break;
case '7':
desetine = desetine + 7 * pow(10, (mocnina * (-1)));
break;
case '8':
desetine = desetine + 8 * pow(10, (mocnina * (-1)));
break;
case '9':
desetine = desetine + 9 * pow(10, (mocnina * (-1)));
break;
default:
break;
}
mocnina++; //povyseni mocniny pro dalsi pozici
}
mocnina = 0; //nastaveni mocniny pro rad jednotek
//prevod cele casti
for (int d = tecka - 1; d >=0 ; d--)
{
switch (cislice[d])
{
case '0':
desetine = desetine + 0 * pow(10, mocnina); //hodnota cifry *10 na cifru
break;
case '1':
desetine = desetine + 1 * pow(10, mocnina);
break;
case '2':
desetine = desetine + 2 * pow(10, mocnina);
break;
case '3':
desetine = desetine + 3 * pow(10, mocnina);
break;
case '4':
desetine = desetine + 4 * pow(10, mocnina);
break;
case '5':
desetine = desetine + 5 * pow(10, mocnina);
break;
case '6':
desetine = desetine + 6 * pow(10, mocnina);
break;
case '7':
desetine = desetine + 7 * pow(10, mocnina);
break;
case '8':
desetine = desetine + 8 * pow(10, mocnina);
break;
case '9':
desetine = desetine + 9 * pow(10, mocnina);
break;
default:
break;
}
mocnina++; //povyseni mocniny pro dalsi pozici
}
}
else
{
//prevod pomoci dekadickeho zapisu disla (mantisa * deset na pozici)
for (int d = strlen(cislice) - 1; d >= 0; d--)
{
switch (cislice[d])
{
case '0':
desetine = desetine + 0 * pow(10, mocnina);
break;
case '1':
desetine = desetine + 1 * pow(10, mocnina);
break;
case '2':
desetine = desetine + 2 * pow(10, mocnina);
break;
case '3':
desetine = desetine + 3 * pow(10, mocnina);
break;
case '4':
desetine = desetine + 4 * pow(10, mocnina);
break;
case '5':
desetine = desetine + 5 * pow(10, mocnina);
break;
case '6':
desetine = desetine + 6 * pow(10, mocnina);
break;
case '7':
desetine = desetine + 7 * pow(10, mocnina);
break;
case '8':
desetine = desetine + 8 * pow(10, mocnina);
break;
case '9':
desetine = desetine + 9 * pow(10, mocnina);
break;
default:
break;
}
mocnina++; //povyseni mocniny pro dalsi pozici
}
}
if (zaporne == -1) //realizace zaporne hodnoty
{
desetine = desetine * (-1);
}
}
//kontolni vypis cisla
printf("\n\nZadane cislo je %f", desetine);
}