Weryfikacja czy wprowadzane znaki w pętli są cyframi

0

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

0

if(znak>=48 && znak <=58) { tak to musi być znak! }

0

Dobra przedobrzyłęm, ale inni też tyle, tyle że na mniejszą skalę.
Zacznij od tego: https://godbolt.org/z/h4Tjo8fbo

0
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

0

Sprawa się trochę skomplikowała bo wprowadzane liczby są %f :(

0

@kszwaba:

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.

0

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;
}
1
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ć

0
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.

0

@kszwaba:

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

0
ZrobieDobrze napisał(a):

@kszwaba:

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.

0

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.

0

@uziom: Widzę, że chat gpt wjechał mocno

0
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...

0

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

1 użytkowników online, w tym zalogowanych: 0, gości: 1