Czy ktoś może podpowiedzieć jak zweryfikować czy wprowadzane znaki są cyframi ?
Mam proste zadanie o do obliczania +, -, *, / na podstawie dwóch wprowadzonych liczb ale
problemem jest dla mnie jak zweryfikować czy wprowadzane są liczby.
Z góry dziękuję za pomoc.
Krzysztof
if(znak>=48 && znak <=58) { tak to musi być znak! }
Dobra przedobrzyłęm, ale inni też tyle, tyle że na mniejszą skalę.
Zacznij od tego: https://godbolt.org/z/h4Tjo8fbo
johnny_Be_good napisał(a):
if(znak>=48 && znak <=58) { tak to musi być znak! }
Nie musi
https://pl.wikipedia.org/wiki/EBCDIC
https://pl.wikipedia.org/wiki/Odra_1300
Sprawa się trochę skomplikowała bo wprowadzane liczby są %f :(
No dobra, ale zacznijmy co rozumiesz przez "wprowadzanie"
Bo na niekórych kanałach nie ma żadnej możliwosci odmowy - można najwyżej "jakos" reagować na wejście, które się otzrynało.
Tak wygląda zadanie:
#include <stdio.h>
#include <stdbool.h>
#include <stddef.h>
#include <stdlib.h>
#include <ctype.h>
int main(void)
{
float a, b, c;
char sign;
printf("Wprowadź pierwszą liczbę:\n");
scanf("%f", &a);
printf("Wprowadź znak:(+, -, *, /\n");
scanf(" %c", &sign);
printf("Wprowadź drugą liczbę:\n");
scanf("%f", &b);
switch(sign) {
case '+':
c = a + b;
printf("Rezultat dodawania: %.4f\n", c); //%.4f zaokrąglenie do 4 miejsc po przecinku
break;
case '-':
c = a - b;
printf("Rezultat odejmowania: %.4f\n", c);
break;
case '*':
c = a * b;
printf("Rezultat mnożenia: %.4f\n", c);
break;
case '/':
if(b != 0){
c = a / b;
printf("Rezultat dzielenia a/b: %.4f\n", c);
printf("Wynik działania został zaokrąglony do 4 miejsc po przecinku");
}else
printf("Wartość drugiej liczby musi być <> 0 !\n");
break;
default:
printf("Złe dane wejsciowe:\n");
break;
}
return 0;
}
kszwaba napisał(a):
Tak wygląda zadanie:
scanf("%f", &a);
Zmień na
int ilość_Ok = scanf("%f", &a);
RTFM https://pl.wikibooks.org/wiki/C/scanf
I to jest wszystko co można, użytkownik MOŻE wpisać "alamakota", i nie zabronisz mu - możesz się tylko o tym dowiedzieć
ZrobieDobrze napisał(a):
kszwaba napisał(a):
Tak wygląda zadanie:
scanf("%f", &a);
Zmień na
int ilość_Ok = scanf("%f", &a);
RTFM https://pl.wikibooks.org/wiki/C/scanf
I to jest wszystko co można, użytkownik MOŻE wpisać "alamakota", i nie zabronisz mu - możesz się tylko o tym dowiedzieć
Ta informacja
"Przykładowe wywołanie służące do pobrania tylko i wyłącznie znaków: - (myślnik), ' (apostrof), (spacja) oraz małych i wielkich liter:
scanf(" %[-' A-Z,a-z]s",&zmienna);
"
Mnie zainteresowała.
Do typu stringowego - pierwotnie pytałeś o numeryczny.
A po drugie i tak na konsoli da się napisać j/w - możesz najwyżej nie zaakceptować skanowania
Zrobienie w pełni dobrze - tylko w prawdziwym GUI, event na każde zdarzenie klawiaturowe *)
*)
trudno to zrobić naprawdę dobrze. Wiele programów GUI np zabezpiecza przez klikaniem na klawiaturze nie-cyfr, ale pozwala wkleić z clipvboardu syfki
ZrobieDobrze napisał(a):
Do typu stringowego - pierwotnie pytałeś o numeryczny.
A po drugie i tak na konsoli da się napisać j/w - możesz najwyżej nie zaakceptować skanowania
Dokładnie, wystarczy wyrzucenie komunikatu błędu
po wykryciu w trakcie skanowania że został wprowadzony inny znak niż cyfra lub kropka.
Możesz użyć funkcji isdigit(), która sprawdza, czy dany znak jest cyfrą. Funkcja ta zwraca wartość true, jeśli znak jest cyfrą, lub false w przeciwnym przypadku. Przykładowy kod wykorzystujący funkcję isdigit():
#include <cstring>
#include <cctype>
using namespace std;
int main() {
char input[100];
cout << "Podaj ciąg znaków: ";
cin >> input;
for (int i = 0; i < strlen(input); i++) {
if (!isdigit(input[i])) {
cout << "Niepoprawny znak: " << input[i] << endl;
return 0;
}
}
cout << "Wprowadzono poprawne liczby." << endl;
return 0;
}
Funkcja stoi()
Możesz również skorzystać z funkcji stoi(), która konwertuje łańcuch znaków na liczbę całkowitą. Jeśli wprowadzony ciąg nie jest liczbą, funkcja zwraca wyjątek std::invalid_argument. Przykładowy kod wykorzystujący funkcję stoi():
#include <string>
using namespace std;
int main() {
string input;
cout << "Podaj ciąg znaków: ";
cin >> input;
try {
int num = stoi(input);
cout << "Wprowadzono poprawną liczbę: " << num << endl;
}
catch (const std::invalid_argument& e) {
cout << "Wprowadzony ciąg nie jest liczbą." << endl;
return 0;
}
return 0;
}
Możesz zastosować jeden z powyższych sposobów lub połączyć je w jednym programie, aby upewnić się, że użytkownik wprowadza poprawne liczby.
@uziom: Widzę, że chat gpt wjechał mocno
Eldorad O. napisał(a):
@uziom: Widzę, że chat gpt wjechał mocno
Myślę, że nawet ChatGPT nie jest aż tak głupi, żeby wołać strlen
w warunku pętli for
...
Nawiązując do mojego komentarza.
cc -> clang
OpenBSD clang version 13.0.0
kod do testów:
#include <stdio.h>
#include <string.h>
int main( void ) {
char word[100];
scanf( "%s", word );
int count = 0;
for( size_t i = 0; i < strlen( word ); i++ ) {
if( word[i] == 'a' ) count++;
}
printf( "ans= %d\n", count );
return 0;
}
log:
bigpc$ cc -Wall -Wextra -pedantic -std=c99 -O3 t.c -o t
bigpc$ ltrace ./t
zlooorzeczyymaaass
ans= 3
bigpc$ kdump | grep -c strlen
1
bigpc$ cc -Wall -Wextra -pedantic -std=c99 -O2 t.c -o t
bigpc$ ltrace ./t
z<oodoewdkaaa
ans= 3
bigpc$ kdump | grep -c strlen
1
bigpc$ cc -Wall -Wextra -pedantic -std=c99 t.c -o t
bigpc$ ltrace ./t
zouuuaaaaz
ans= 4
bigpc$ kdump | grep -c strlen
11
bigpc$ cc -Wall -Wextra -pedantic -std=c99 -O1 t.c -o t
bigpc$ ltrace ./t
zjikswhdcwehd
ans= 0
bigpc$ kdump | grep -c strlen
1
Tam gdzie nie wybrałem to przyjmijmy bez opta. na -O0 wywoływał za każdym razem.
bigpc$ cc -Wall -Wextra -pedantic -std=c99 -O0 t.c -o t
bigpc$ ltrace ./t
efwefrgsaf
ans= 1
bigpc$ kdump | grep -c strlen
11