NOVINKA - Online rekvalifikační kurz Java programátor. Oblíbená a studenty ověřená rekvalifikace - nyní i online.
NOVINKA – Víkendový online kurz Software tester, který tě posune dál. Zjisti, jak na to!
Avatar
Bimbo
Člen
Avatar
Bimbo:10.3.2016 20:24

Zdravím.
Mam string, který je zadáván uživatelem.
Vím že od 6 pozice do konce by mělo být čislo.

poslanecislo = poslanyretezec­.substring(6);

Potřebují zjistit zda je to fakt čislo a pak to až převést na integer.

Editováno 10.3.2016 20:25
 
Odpovědět
10.3.2016 20:24
Avatar
Adam Ježek
Tvůrce
Avatar
Adam Ježek:10.3.2016 20:39

Nejdříve naimportuješ ctype:

#include <ctype.h>

a potom přes cyklus projedeš každý znak řetězce funkcí isDigit()

 String s1 = "abc123";
 bool s1JeCislo = true;
 for(int i = 0; i < s1.length(); i++) {
    if(!isDigit(s1[i])) { s1JeCislo = false;}
 }
 Serial.println(String(s1JeCislo)); //0

 String s2 = "123";
 bool s2JeCislo = true;
 for(int i = 0; i < s2.length(); i++) {
    if(!isDigit(s2[i])) { s2JeCislo = false;}
 }
Serial.println(String(s2JeCislo)); //1
Editováno 10.3.2016 20:42
Nahoru Odpovědět
10.3.2016 20:39
Počkej chvíli, poradím se s křišťálovou koulí.
Avatar
Adam Ježek
Tvůrce
Avatar
Odpovídá na Adam Ježek
Adam Ježek:10.3.2016 20:50

Možná to rovnou zabalit do funkce:

bool JeCislo(String s) {
  bool StrJeCislo = true;
  for(int i = 0; i < s.length(); i++) {
    if(!isDigit(s[i])) { StrJeCislo = false; break;}
  }
return StrJeCislo;
}

JeCislo("abc");  //false
JeCislo("abc123");  //false
JeCislo("123");  //true

Stále platí že musíš naimportovat ctype.h

Editováno 10.3.2016 20:51
Nahoru Odpovědět
10.3.2016 20:50
Počkej chvíli, poradím se s křišťálovou koulí.
Avatar
Martin Dráb
Tvůrce
Avatar
Odpovídá na Bimbo
Martin Dráb:10.3.2016 20:55

No, bude to fungovat i na záporná čísla?

Co něco na způsob tohoto?

int cislo = 0;
bool jeCislo = (isDigit(str[0]) || str[0] == '-');

if (jeCislo) {
  bool negative = false;
  int start = 0;

  negative = (str[0] == '-');
  if (negative)
    ++start;

  jeCislo = start < str.length;
  if (jeCislo) {
    for (int i = start; i < str.length; ++i) {
      jeCislo = isDigit(str[i]);
      if (!jeCislo)
        break;

      cislo = cislo*10 + (str[i] - '0');
    }

    if (jeCislo) {
      if (negative)
        cislo = -cislo;
    }
  }
}

Ber to ale spíš jako inspiraci.

Editováno 10.3.2016 20:57
Nahoru Odpovědět
10.3.2016 20:55
2 + 2 = 5 for extremely large values of 2
Avatar
Adam Ježek
Tvůrce
Avatar
Odpovídá na Martin Dráb
Adam Ježek:10.3.2016 21:02

Na záporný sem zapoměl, ale dá se to vyřešit snadněji. Prostě ten mínus smažu, pokud je na začátku a zkontroluju, jestli je to číslo:

bool JeCislo(String s) {
  bool StrJeCislo = true;
  if(s[0] == '-') { s = s.substring(1);}
  for(int i = 0; i < s.length(); i++) {
    if(!isDigit(s[i])) { StrJeCislo = false; break;}
  }
return StrJeCislo;
}

Teď mě ještě napadlo, jak to máš s desetinejma číslama? Tady by ale mělo stačit si zjistit přes StringIndexOf pozici první čárky (pokud je) a smazat ji (ale nepoužívat na to StringReplace, ten by zrušil všechny čárky a pak by 15,58,8 mohlo být bráno jako platné číslo).

Nahoru Odpovědět
10.3.2016 21:02
Počkej chvíli, poradím se s křišťálovou koulí.
Avatar
tomisoka
Tvůrce
Avatar
Odpovídá na Bimbo
tomisoka:10.3.2016 21:18

Moje mírně ořezaná fce na načítání double ze stringu:

bool isNum(char *s){
        uint32_t i=0;
        bool is_dot=0;

        if(s[i]=='-')i++;

        for(;s[i];++i){
                if(s[i] == '.' || s[i] == ','){
                        if(is_dot)
                                return 0;
                        else
                                is_dot = 1;
                }else if(s[i] < '0' || s[i] > '9')return 0;
        }
        return 1;
}

popřípadě pokud to chceš mít v jedné fci:

bool strToInt(char *pos, int32_t& returned, uint32_t len, uint32_t base){
        uint32_t i=0;
        returned=0;
        char temp;

        if(base>26*2+10)return 1;

        if(*pos=='-')i++;
        for(; i<len;++i){
                temp = pos[i];
                if(temp<=0x20)break;
                returned*=base;

                if(temp>='0' && temp<='9'){
                        temp-='0';
                        if(base<=temp)return 1;
                        returned+=temp;
                }else if(temp>='A' && temp <= 'Z'){
                        temp = temp-'A'+10;
                        if(base<=temp)return 1;
                        returned+=temp;
                }else if(temp>='a' && temp <= 'z'){
                        temp = temp-'a'+36;
                        if(base<=temp)return 1;
                        returned+=temp;
                }else return 1;
        }
        if(*pos=='-')returned*=-1;
        return 0;
}

Návratová hodnota 1 pro neúspěch.
Co nepotřebuješ odstraň.

 
Nahoru Odpovědět
10.3.2016 21:18
Avatar
Martin Dráb
Tvůrce
Avatar
Odpovídá na Adam Ježek
Martin Dráb:10.3.2016 21:40

V původním dotazu je:
Potřebují zjistit zda je to fakt čislo a pak to až převést na integer.

Nahoru Odpovědět
10.3.2016 21:40
2 + 2 = 5 for extremely large values of 2
Avatar
ostrozan
Tvůrce
Avatar
ostrozan:10.3.2016 21:57

Pěkné a užitečné konstrukce, ale nebylo by jednodušší to kontrolovat po zadání znaku ?

Taky tam ten uživatel těžko bude zadávat záporná, nebo desetinná čísla - nejspíš se jedná o nějaký kód, nebo typové číslo výrobku - hádal bych.

 
Nahoru Odpovědět
10.3.2016 21:57
Avatar
Bimbo
Člen
Avatar
Bimbo:10.3.2016 22:47

:-)
Žadné zaporné číslo tam nebude.
1 až 1000
Mi jde jen o to aby se nepřeklep a misto 1234 nezadal třeba 123h4

cislo = poslanecislo.to­Int();
Už funkce toInt() by měla vracet nějaky kod chby pokud budu chtít převest něco co integer není, ne?

 
Nahoru Odpovědět
10.3.2016 22:47
Avatar
Martin Dráb
Tvůrce
Avatar
Odpovídá na Bimbo
Martin Dráb:10.3.2016 22:54

V případě, že se konverze nepodaří, varcí nulu.

Takže pokud tvůj program s nulou jako validním číslem nepracuje, tak je to v pořádku.

https://www.arduino.cc/…/StringToInt

Nahoru Odpovědět
10.3.2016 22:54
2 + 2 = 5 for extremely large values of 2
Avatar
Adam Ježek
Tvůrce
Avatar
Odpovídá na Bimbo
Adam Ježek:10.3.2016 22:54

Když funkci toInt nepředhodíš validní číslo, tak vrátí 0, což je ale taky číslo. Jestli ti ta 0 nevadí, můžeš na to rovnou volat toInt.

Nahoru Odpovědět
10.3.2016 22:54
Počkej chvíli, poradím se s křišťálovou koulí.
Avatar
Adam Ježek
Tvůrce
Avatar
Odpovídá na Martin Dráb
Adam Ježek:10.3.2016 22:57

Tohle mi nějak nedošlo, máš pravdu, desetinné tu logicky být nemůže. ¨
Každopádně stále považuji moje řešení za přehlednější a úspornější.

Nahoru Odpovědět
10.3.2016 22:57
Počkej chvíli, poradím se s křišťálovou koulí.
Avatar
Martin Dráb
Tvůrce
Avatar
Odpovídá na Adam Ježek
Martin Dráb:10.3.2016 23:51

To je pravda. Moje řešení tam navíc provádí konverzi toho čísla na integer. Ale pokud toInt() vyhovuje, tak je samozřejmě nejlepším řešením.

Nahoru Odpovědět
10.3.2016 23:51
2 + 2 = 5 for extremely large values of 2
Avatar
Adam Ježek
Tvůrce
Avatar
Odpovídá na Martin Dráb
Adam Ježek:10.3.2016 23:57

Převod se dá udělat kratší pomocí toInt, navíc i bez nutnosti použití nějaké meziproměnné.
Nechci tu rozpoutat flame, možností je více, ale tohle je cesta nejmenšího odporu.

Nahoru Odpovědět
10.3.2016 23:57
Počkej chvíli, poradím se s křišťálovou koulí.
Děláme co je v našich silách, aby byly zdejší diskuze co nejkvalitnější. Proto do nich také mohou přispívat pouze registrovaní členové. Pro zapojení do diskuze se přihlas. Pokud ještě nemáš účet, zaregistruj se, je to zdarma.

Zobrazeno 14 zpráv z 14.