Milan
Offline
Sr. Member
Karma: 0
Posts: 366
|
 |
« on: October 03, 2012, 05:05:32 am » |
Ho trovato un po di esempi e costruito una semplice funzione string to int. 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 num = num * 10 + (inStr - '0'); Soprattutto (inStr - '0') Cosa fa esattamente? Grazie N
|
|
|
|
|
Logged
|
|
|
|
|
Forum Moderator
Italy
Offline
Brattain Member
Karma: 226
Posts: 16973
Don't know what I do
|
 |
« Reply #1 on: October 03, 2012, 06:21:30 am » |
(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.
|
|
|
|
|
Logged
|
|
|
|
|
Offline
Edison Member
Karma: 26
Posts: 1339
You do some programming to solve a problem, and some to solve it in a particular language. (CC2)
|
 |
« Reply #2 on: October 03, 2012, 06:30:16 am » |
inStr - '0' non ha senso. (inStr[i] - '0') invece produce un intero che ha il valore corrispondente alla cifra '0'..'9' memorizzata nella posizione i della stringa. (edit: [i] viene interpretato come l'inizio del tag 'italics' e viene perciò stampato solo all'interno di una sezione 'code'...)
|
|
|
|
« Last Edit: October 03, 2012, 06:32:19 am by tuxduino »
|
Logged
|
|
|
|
|
Milan
Offline
Sr. Member
Karma: 0
Posts: 366
|
 |
« Reply #3 on: October 03, 2012, 07:21:04 am » |
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
|
|
|
|
|
Logged
|
|
|
|
|
Offline
Edison Member
Karma: 26
Posts: 1339
You do some programming to solve a problem, and some to solve it in a particular language. (CC2)
|
 |
« Reply #4 on: October 03, 2012, 07:30:59 am » |
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é).
|
|
|
|
|
Logged
|
|
|
|
|
Offline
Sr. Member
Karma: 6
Posts: 462
|
 |
« Reply #5 on: October 03, 2012, 07:32:41 am » |
piuttosto usa
istringstream (inStr)>>a;(richiede #include <sstream>) o atoi(inStr.c_str);
|
|
|
|
|
Logged
|
|
|
|
|
Offline
Sr. Member
Karma: 6
Posts: 462
|
 |
« Reply #6 on: October 03, 2012, 07:35:01 am » |
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..
|
|
|
|
|
Logged
|
|
|
|
|
0
Offline
Tesla Member
Karma: 87
Posts: 8478
:(){:|:&};:
|
 |
« Reply #7 on: October 05, 2012, 03:24:55 am » |
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à 
|
|
|
|
« Last Edit: October 05, 2012, 05:06:53 am by lesto »
|
Logged
|
|
|
|
|
0
Offline
Tesla Member
Karma: 87
Posts: 8478
:(){:|:&};:
|
 |
« Reply #8 on: October 05, 2012, 03:28:29 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
|
|
|
|
|
Logged
|
|
|
|
|
Offline
Edison Member
Karma: 26
Posts: 1339
You do some programming to solve a problem, and some to solve it in a particular language. (CC2)
|
 |
« Reply #9 on: October 05, 2012, 03:34:09 am » |
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).
|
|
|
|
|
Logged
|
|
|
|
|
Milan
Offline
Sr. Member
Karma: 0
Posts: 366
|
 |
« Reply #10 on: October 05, 2012, 03:36:50 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.
|
|
|
|
|
Logged
|
|
|
|
|
Offline
Edison Member
Karma: 26
Posts: 1339
You do some programming to solve a problem, and some to solve it in a particular language. (CC2)
|
 |
« Reply #11 on: October 05, 2012, 04:51:36 am » |
atoi che richiedeva un include anche se non ricordo quale mi pare stdlib.h
|
|
|
|
|
Logged
|
|
|
|
|
0
Offline
Tesla Member
Karma: 87
Posts: 8478
:(){:|:&};:
|
 |
« Reply #12 on: October 05, 2012, 05:06:39 am » |
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/
|
|
|
|
« Last Edit: October 05, 2012, 05:08:27 am by lesto »
|
Logged
|
|
|
|
|
Offline
Edison Member
Karma: 26
Posts: 1339
You do some programming to solve a problem, and some to solve it in a particular language. (CC2)
|
 |
« Reply #13 on: October 05, 2012, 05:20:41 am » |
(atoi) non mi era piaciuta. Sarei curioso di sapere perché 
|
|
|
|
|
Logged
|
|
|
|
|
Milan
Offline
Sr. Member
Karma: 0
Posts: 366
|
 |
« Reply #14 on: October 05, 2012, 06:22:57 am » |
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
|
|
|
|
|
Logged
|
|
|
|
|
|