Avatar
Bimbo
Člen
Avatar
Bimbo:

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. března 20:25
 
Odpovědět 10. března 20:24
Avatar
Adam Ježek
Tým ITnetwork
Avatar
Adam Ježek:

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. března 20:42
Nahoru Odpovědět 10. března 20:39
Programátor dělá co může. Počítač co chce. | Pokud mi dáš mínus, tak prosim, napiš proč!
Avatar
Adam Ježek
Tým ITnetwork
Avatar
Odpovídá na Adam Ježek
Adam Ježek:

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. března 20:51
Nahoru Odpovědět 10. března 20:50
Programátor dělá co může. Počítač co chce. | Pokud mi dáš mínus, tak prosim, napiš proč!
Avatar
Martin Dráb
Redaktor
Avatar
Odpovídá na Bimbo
Martin Dráb:

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. března 20:57
Nahoru Odpovědět 10. března 20:55
2 + 2 = 5 for extremely large values of 2
Avatar
Adam Ježek
Tým ITnetwork
Avatar
Odpovídá na Martin Dráb
Adam Ježek:

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. března 21:02
Programátor dělá co může. Počítač co chce. | Pokud mi dáš mínus, tak prosim, napiš proč!
Avatar
tomisoka
Redaktor
Avatar
Odpovídá na Bimbo
tomisoka:

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. března 21:18
Avatar
Martin Dráb
Redaktor
Avatar
Odpovídá na Adam Ježek
Martin Dráb:

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. března 21:40
2 + 2 = 5 for extremely large values of 2
Avatar
ostrozan
Redaktor
Avatar
ostrozan:

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. března 21:57
Avatar
Bimbo
Člen
Avatar
Bimbo:

:-)
Ž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. března 22:47
Avatar
Martin Dráb
Redaktor
Avatar
Odpovídá na Bimbo
Martin Dráb:

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. března 22:54
2 + 2 = 5 for extremely large values of 2
Avatar
Adam Ježek
Tým ITnetwork
Avatar
Odpovídá na Bimbo
Adam Ježek:

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  +1 10. března 22:54
Programátor dělá co může. Počítač co chce. | Pokud mi dáš mínus, tak prosim, napiš proč!
Avatar
Adam Ježek
Tým ITnetwork
Avatar
Odpovídá na Martin Dráb
Adam Ježek:

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. března 22:57
Programátor dělá co může. Počítač co chce. | Pokud mi dáš mínus, tak prosim, napiš proč!
Avatar
Martin Dráb
Redaktor
Avatar
Odpovídá na Adam Ježek
Martin Dráb:

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. března 23:51
2 + 2 = 5 for extremely large values of 2
Avatar
Adam Ježek
Tým ITnetwork
Avatar
Odpovídá na Martin Dráb
Adam Ježek:

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  +1 10. března 23:57
Programátor dělá co může. Počítač co chce. | Pokud mi dáš mínus, tak prosim, napiš proč!
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.