Arduino Forum

International => Italiano => Software => Topic started by: contecavour on Oct 03, 2012, 12:05 pm

Title: Operatore - con String
Post by: contecavour on Oct 03, 2012, 12:05 pm
Ho trovato un po di esempi e costruito una semplice funzione string to int.

Code: [Select]
int StringaToIntero (String inStr) {
  int i;
  int lung;
  int num = 0;
  lung = inStr.length();
  Serial.println(lung);
  for (int i = 0; i < lung; i++) {
     num = num * 10 + (inStr[i] - '0');
     Serial.println(num);
  }   
  return num;   
 
}


Direi che funziona, ma non mi spiego il
Quote
num = num * 10 + (inStr - '0');


Soprattutto
Quote
(inStr - '0')


Cosa fa esattamente?
Grazie
N




Title: Re: Operatore - con String
Post by: leo72 on Oct 03, 2012, 01:21 pm


Quote
(inStr - '0')


Cosa fa esattamente?


Semplicemente sottrae al valore di inStr il valore del codice ASCII del carattere '0'. Se noti è messo fra apici singoli, quindi viene detto al compilatore di considerare il carattere '0' col suo valore ASCII, 48.
Title: Re: Operatore - con String
Post by: marcello.romani on Oct 03, 2012, 01:30 pm
Code: [Select]
inStr - '0' non ha senso.
Code: [Select]
(inStr[i] - '0') invece produce un intero che ha il valore corrispondente alla cifra '0'..'9' memorizzata nella posizione i della stringa.

(edit:
Code: [Select]
[i] viene interpretato come l'inizio del tag 'italics' e viene perciò stampato solo all'interno di una sezione 'code'...)
Title: Re: Operatore - con String
Post by: contecavour on Oct 03, 2012, 02:21 pm
Grazie Leo.
Chiarissimo.

Si tuxduino, copiando e incollando si è mangiato alcuni caratteri.
Mi è chiaro.
Aspettandomi solo cifre e sottraendo  il valore ascii della cifra a quello dello 0 si ottiene appunto il valore della cifra.
Quindi mi sta benissimo.
Dato che sto usando un keypad in cui ho disabilitato le 4 lettere ABCD e se premo asterisco o diesi faccio altre cose (reset e invio).

La cosa che non sapevo era che '0' era il codice ASCII del carattere.
Ma quindi inStr da solo è il carattere e dato che li tutto è intero automaticamente fa il cast del codice ASCII in intero?
Perchè se faccio print(inStr) stampa il carattere.

Grazie a tutti


Title: Re: Operatore - con String
Post by: marcello.romani on Oct 03, 2012, 02:30 pm
L'apparente incongruenza di questa situazione è dovuta alle conversioni implicite char => int e viceversa che il compilatore applica quando necessario (in realtà la conversione consiste proprio nel prendere il char ed usarlo pari pari come fosse un int, senza "convertire" alcunché).
Title: Re: Operatore - con String
Post by: m_ri on Oct 03, 2012, 02:32 pm
piuttosto usa

istringstream (inStr)>>a;(richiede #include <sstream>)
o
atoi(inStr.c_str);
Title: Re: Operatore - con String
Post by: m_ri on Oct 03, 2012, 02:35 pm
il metodo print accetta stringhe(nel tuo caso è una stringa contenente un solo caratteri),interi...
in realtà ci sono più metodi print,uno che accetta come parametro una stringa,un altro accetta come parametro un interi,etc..
Title: Re: Operatore - con String
Post by: lestofante on Oct 05, 2012, 10:24 am
Quote
Ma quindi inStr da solo è il carattere e dato che li tutto è intero automaticamente fa il cast del codice ASCII in intero?
Perchè se faccio print(inStr) stampa il carattere.


un char è un numero. se prendi un int e ci schiaffi 48, e poi fai una write (attento, una write, non una print che fa "del lavoro sporco" di nascosto) vedrai sol monito seriale comparire un 0!

la println invece si accorge del TIPO di dato, e se trova un int, un float o un double, "di nascosto" estrae le varie cifre una per una e le converte in una stringa (sommando '0'!) mentre per i char/stringhe non fa nessuna conversione, dando questa senzazione che un char e un uint8_t (leggi unsigned byte) siano due cose differenti.

Altro trucco: se guardi la tabella ASCII le lettere sono tutte di seguito. Quindi puoi usare un trucco simile per convertire una lettere da maiuscolo a miniscolo:
minuscolo = maiuscolo + 'A'-'a';
e viceversa:
maiuscolo = minuscolo + 'a'-'A';

oppure per scorrere tutto l'afabeto puoi fare
for (int i='a'; i<='z';i++){
   char lettera = i;
}

non dare un gioco del genere così per scontato; osserva l'EBCDIC, un charset dell'IBM che esiste ancora dai tempi delle schede perforate, e capirai come "trucchi" così banali sono in realtà frutto di un'evoluzione e della genialità  XD
Title: Re: Operatore - con String
Post by: lestofante on Oct 05, 2012, 10:28 am

piuttosto usa

istringstream (inStr)>>a;(richiede #include <sstream>)
o
atoi(inStr.c_str);


sconsiglio.
sia atoi (string.h) che >> (sstream.h) sono librerie molto pesanti, anche se vengono estratte solo le parti realmente utilizzate possono incidere molto, forse troppo sul peso dello sketch, perchè sono funzioni generiche a discapito della dimensione del codice. Meglio una funzioncina ad-hoc
Title: Re: Operatore - con String
Post by: marcello.romani on Oct 05, 2012, 10:34 am
Quote
un char è un numero. se prendi un int e ci schiaffi 48, e poi fai una write (attento, una write, non una print che fa "del lavoro sporco" di nascosto) vedrai sol monito seriale comparire un 48!


No, vedrai comparire il carattere 0 (zero), il cui codice ASCII è appunto 48 (in base 10).
Title: Re: Operatore - con String
Post by: contecavour on Oct 05, 2012, 10:36 am
Arrivo dai mainframe IBM, Unix e poi dos, quindi sia EBCDIC che ASCII e la loro aritmetica mi + molto chiara (e semplice peraltro).
Come prima prova avevo proprio usato atoi che richiedeva un include anche se non ricordo quale, ma non mi era piaciuta.
Title: Re: Operatore - con String
Post by: marcello.romani on Oct 05, 2012, 11:51 am
Quote
atoi che richiedeva un include anche se non ricordo quale


mi pare stdlib.h
Title: Re: Operatore - con String
Post by: lestofante on Oct 05, 2012, 12:06 pm

Quote
un char è un numero. se prendi un int e ci schiaffi 48, e poi fai una write (attento, una write, non una print che fa "del lavoro sporco" di nascosto) vedrai sol monito seriale comparire un 48!


No, vedrai comparire il carattere 0 (zero), il cui codice ASCII è appunto 48 (in base 10).


sì, errore mio, correggo :)


Arrivo dai mainframe IBM, Unix e poi dos, quindi sia EBCDIC che ASCII e la loro aritmetica mi + molto chiara (e semplice peraltro).
Come prima prova avevo proprio usato atoi che richiedeva un include anche se non ricordo quale, ma non mi era piaciuta.


ma arduino usa ascii..
comunque confermo che la atoi usa stdlib.h: http://www.cplusplus.com/reference/clibrary/cstdlib/atoi/
Title: Re: Operatore - con String
Post by: marcello.romani on Oct 05, 2012, 12:20 pm
Quote
(atoi) non mi era piaciuta.


Sarei curioso di sapere perché :)
Title: Re: Operatore - con String
Post by: contecavour on Oct 05, 2012, 01:22 pm
Oggi sono altrove, appena ho il codice sotto mano cerco di capire cosa non mi era piaciuto.
In prima battuta potrebbe essere stato proprio per l'include, sviluppo da 30 anni (mamma mia) e ormai come filosofia ho: <<meno includo e meno componenti uso meglio è>>.
Ho passato notti a riscrivere codice perchè librerie o componenti non venivano più supportati nelle release successiva di un ambiente...

In seconda battuta potrebbe essere che chiedevo un lavoro aggiuntivo quindi già che c'ero ho preferito farmi una versione io prendendo il codice e modificandolo. Forse qui ho omesso che come input uso una tastiera 4x4 (non I2C) è ho disabilitato la riga con 4 lettere, quindi ho la certezza che possano entrare solo 12 caratteri.

N
Title: Re: Operatore - con String
Post by: marcello.romani on Oct 05, 2012, 02:57 pm
atoi() fa parte della libreria standard del C, quindi sulla sua presenza in un dato ambiente direi che si può stare abbastanza tranqulli a prescindere dagli aggiornamenti :)
Title: Re: Operatore - con String
Post by: contecavour on Oct 05, 2012, 03:34 pm
Non entravo nel merito di stdlib.h, ma di usare un include.
Il mio linguaggio preferito è Delphi che non so se conosci, ma è come dire li..abbassare gli uses...per evitare definizioni ricorsive.
Insomma, diventa uno stile a priori.

Mi viene un dubbio, accetta String in ingresso o pchar?

N
Title: Re: Operatore - con String
Post by: marcello.romani on Oct 05, 2012, 04:25 pm
Delphi lo conosco bene di nome (il ns. gestionale ad esempio è scritto in Delphi). Usato non proprio, ci ho giocato tanto tempo fa... (ma col turbo pascal ero bravino... :) )

Quote
Mi viene un dubbio, accetta String in ingresso o pchar?


atoi() accetta pchar come argomento (const char* nel gergo C/C++)

http://www.cplusplus.com/reference/clibrary/cstdlib/atoi/

Quando si passa dagli array null-terminated del C ad una classe stringa si cambia approccio, perché la rappresentazione stringa è già nell'oggetto stesso. Quindi si dota la classe stringa di un metodo tipo int toInt(), e/o si definisce l'operatore di casto-to-int per la classe, in modo che String s="10"; int i = (int)s; abbia un senso. VB.net usa un approccio inverso: fornisce una classe per ogni tipo nativo, e ognuna di queste classi ha un metodo di classe che fa il parsing di una stringa e ritorna il tipo di dato numerico corrispondente. Ad esempio i = Integer.parse(str).
Title: Re: Operatore - con String
Post by: contecavour on Oct 05, 2012, 04:29 pm
Allora era per quello.
Me ne ero fatto uno che accettasse in entrata il mio tipo di dato e uscisse con quello che mi serviva.

Quote
VB.net


Ecco VB.net penso che sia uno di quei linguaggi che non userò mai (Dio mi aiuti), se devo lavorare in .Net che sia c#.

N
Title: Re: Operatore - con String
Post by: lestofante on Oct 05, 2012, 04:57 pm
ho usato il VB (tradizionale), ma ora che son stato costretto ad usare il .net mi son buttato sul c#.
è un casino quando programmi mezaz giornata in VB e mezza in c o altro, ti ritrovi a mischiar le sintassi.

Quote
fornisce una classe per ogni tipo nativo, e ognuna di queste classi ha un metodo di classe che fa il parsing di una stringa e ritorna il tipo di dato numerico corrispondente. Ad esempio i = Integer.parse(str).


java fa un mischione, perchè ha sia gli oggetti (Integer, Float, etc..) che i tipi primitivi (int, float, etc..). Se usi gli oggetti hai i metodoti toInt() etc, se usi i primitivi o le stringhe usi dei metodi statici delle classi sopracitate.
Title: Re: Operatore - con String
Post by: marcello.romani on Oct 05, 2012, 05:21 pm
Vb.net fa lo stesso "mischione".
Title: Re: Operatore - con String
Post by: cyberhs on Oct 05, 2012, 07:35 pm
Anche la classe String possiede il suo bravo toInt(), peccato che (nonostante le segnalazioni) questa funzione non sia documentata!

La uso spesso per introdurre numerici da Monitor.

Ettore Massimo Albani
Title: Re: Operatore - con String
Post by: m_ri on Oct 05, 2012, 09:36 pm
@lesto: son d'accordo che gli stream(e anche le string) non vadano molto bene con arduino se fai qlks di serio,e aggiungo come motivo(oltre ai soliti noti) il fatto che fanno allocazioni/dealloc,e arduino dopo un po' può piantarsi in casi particolari..
atoi mi sembra invece una buona scelta,comunque meglio di quanto possa fare un programmatore normale..contando che di solito a ste librerie vengano fatte molte ottimizzazioni..