Go Down

Topic: convertire un intero in una stringa ... (Read 4073 times) previous topic - next topic

tuxduino

Appunto, dov'è il problema ? Le ultime 4 righe di codice che hai postato compilano.

Finché ti limiti a qualche riga di codice decontestualizzata è difficile essere di aiuto... Quando si dice "posta il codice che ti dà problemi", si intende _tutto_ lo sketch, con indicazione del punto "critico".

Paolo S

vi chiedo scusa .. ma qui non ho com me l'ide ne il micro per fare le prove..

io converto l'intero in una stringa correttamente facendo così:
String keyPIN;
int intPIN = 123;

keyPIN = String(intPIN);

e fin qui va tutto bene..
adesso devo anteporre alla stringa keyPIN che ha assunto il valore "123" uno zero, un char '0', mettere quindi nella stessa stringa keyPIN  prima '0', poi "123" .. per ottenere questo "0123" ....

non sono riuscito a concatenare due stringhe mettendole nella stessa variabile di prima cioè vorrei fare:
keyPIN = '0' + keyPIN;
oppure
keyPIN = '0' + String(intPIN);
ma nessuna di queste due forme compila....
per adesso non devo stampare nulla devo semplicemente anteporre degli zeri davanti ad una stringa, non un vettore di char,  quando questa e composta da meno di 6 caratteri numerici.... non so me'rendo!!!

stasera dopo cena potro riprovare .. scusate se vi sto annoiando... sono fuso .....porka miseria ....
ciao







tuxduino

No prob :)

Ma non capisco cosa c'è che non va nella sprintf ? :)

pablos

#18
Jan 23, 2013, 08:53 pm Last Edit: Jan 23, 2013, 08:58 pm by pablos Reason: 1
Quote
non sono riuscito a concatenare due stringhe mettendole nella stessa variabile di prima cioè vorrei fare:
keyPIN = '0' + keyPIN;
oppure
keyPIN = '0' + String(intPIN);
ma nessuna di queste due forme compila....


Non ho capito, c'e' gia una libreria interna che usa quello che state dicendo sprintf, buffer ecc, perchè glieli fare rifare quando (String) raccoglie già le istruzioni sopracitate?


ti ho fatto gli esempi prima

Es:
Serial.println("mia stringa " + (String)intA);
uscita "mia stringa 123"

invece di mia stringa ci metti 0
keyPIN = "0" + String(intPIN);
Se intPIN lo hai già convertito in String non è più necessario usare (String)
lo scriverai direttamente
keyPIN = "0" + intPIN;  // >>>risultato 0123


Le stringhe si trattano tra " " (virgolette) i char tra ' ' (apici)

ciao


no comment

tuxduino

String è fortemente sconsigliata per problemi di frammentazione della RAM (se ricordo bene), quindi un po' per questo un po' per abitudine non la uso quasi mai su Arduino. Ma certamente è più intuitivo e "facile" concatenare le stringhe con l'operatore + di String che alambiccarsi con buffer, s(n)printf e compagnia...  :P

Paolo S

Ciao Pablos

non sò perchè ma questo:

Es:
Serial.println("mia stringa " + (String)intA);
uscita "mia stringa 123"
invece di mia stringa ci metti 0
keyPIN = "0" + String(intPIN);


non funziona.... cioè compila, ma poi mi blocca il micro....

se faccio questo
keyPIN = "0" + String(intPIN) + "/0";
di nuovo, compila, apparentemente il micro funziona, perchè tutto il resto funziona... ma non mi funziona il riconoscimento del pin....


comunque ho risolto così:
Code: [Select]

  unsigned int  intPIN = ((EEPROM.read(6)) | (EEPROM.read(7)<<8));         // legge il  PIN compreso tra 00000 e 65535 dalla eeprom;
           char bufferPIN[6];
           String passPIN;    // PIN in formato stringa
           for (int i=String(intPIN).length(); i<5 ; i++){ passPIN += "0";} // aggiunge eventuali zero
           passPIN += (String)intPIN; // acquisisce il PIN
           // Serial.print (passPIN);

           // cerca la password nei primi passKey.length() caratteri
           passBool = (char_DTMF_buffer.substring(0, passPIN.length()) == passPIN);

questo di sopra è l'utilizzo completo di ciò di cui avevo bisogno, in particolare:

prima aggiungo gli zeri che mi servono con questa istruzione:
passPIN += "0";

poi aggiungo il PIN vero e proprio, convertendolo da intero a stringa:
passPIN += (String)intPIN;

adesso non ricordo se ho propvato anche questo:
passPIN += String(intPIN);

comunque funziona benissimo
poi faccaio il riconoscimento del codicePIN nel comando ricevuto con l'istruzoine successiva...

grazie
ciao




tuxduino

Se i due pin, quello inserito dall'utente e quello memorizzato, sono entrambi numeri senza segno, non faresti prima a confrontarli direttamente come tali ?

Code: [Select]
unsigned int enteredPin = atoi(char_DTMF_buffer);
unsigned int  storedPin = ((EEPROM.read(6)) | (EEPROM.read(7)<<8));
passBool = enteredPin == storedPin



pablos

ma soprattutto che significa
Code: [Select]
intPIN = ((EEPROM.read(6)) | (EEPROM.read(7)<<8));  //legge il  PIN compreso tra 00000 e 65535 dalla eeprom;

in ogni cella della eeprom ci scrivi un byte, il numero del pin non supera certo il 255, perchè usi l'intero?
no comment

tuxduino


ma soprattutto che significa
Code: [Select]
intPIN = ((EEPROM.read(6)) | (EEPROM.read(7)<<8));  //legge il  PIN compreso tra 00000 e 65535 dalla eeprom;

in ogni cella della eeprom ci scrivi un byte, il numero del pin non supera certo il 255, perchè usi l'intero?


Guarda che PIN = Personal Identification Number, cioè sinonimo di password, non pin = piedino del micro.

Forse però rileggendo quell'istruzione mancano un paio di cast a int. Appena metto le mani su una UNO provo...

tuxduino

Mah, sembra che il cast non serva, comunque io lo metterei per stare tranquillo...

Code: [Select]
#include <EEPROM.h>


unsigned int numeroDaScrivere = 65230;
int indirizzoEE = 1000;

void scriviIntero(unsigned int valore, int indirizzo) {
    byte loByte = valore & 0x00FF;
    byte hiByte = valore >> 8;
   
    EEPROM.write(indirizzo, loByte);
    EEPROM.write(indirizzo + 1, hiByte);
}


unsigned int leggiIntero(int indirizzo) {
    byte loByte;
    byte hiByte;
   
    loByte = EEPROM.read(indirizzo);
    hiByte = EEPROM.read(indirizzo + 1);
   
    //return (((unsigned int)hiByte) << 8) | ((unsigned int)loByte);
    return EEPROM.read(indirizzo + 1) << 8 | EEPROM.read(indirizzo);
}
   
   
void setup() {
    Serial.begin(115200);
}


void loop() {
    if (Serial.available() > 0) {
        char ch = Serial.read();
       
        switch(ch) {
            case 'r':
                Serial.println(leggiIntero(indirizzoEE));
                break;
               

            case 'w':
                scriviIntero(numeroDaScrivere, indirizzoEE);
                Serial.println("scritto");
                break;
        }
    }
}

Paolo S

#25
Jan 24, 2013, 02:15 pm Last Edit: Jan 24, 2013, 02:24 pm by Paolo S Reason: 1

Se i due pin, quello inserito dall'utente e quello memorizzato, sono entrambi numeri senza segno, non faresti prima a confrontarli direttamente come tali ?
Code: [Select]
unsigned int enteredPin = atoi(char_DTMF_buffer);
unsigned int  storedPin = ((EEPROM.read(6)) | (EEPROM.read(7)<<8));
passBool = enteredPin == storedPin



No. Il numero inserito proviene dalla decodifica di un tono audio, che costruisce i caratteri uno per uno, ricevendoli e decodificandoli char per char, che io metto in una stringa ...
mentre il PIN memorizzato in due byte di eeprom è un intero (0 - 65535),  che ricostruisco così quando lo leggo: unsigned int  storedPin = ((EEPROM.read(6)) | (EEPROM.read(7)<<8));
anche se io lo chiamo passPIN...

potrei al contrario, fare così: unsigned int enteredPin = atoi(char_DTMF_buffer); .. ma a parte che nel  buffer cè anche altra roba, il PIN è costituito solo i primi char del buffer..

anzi forse tu intendi dire che anzicchè convertire in String il PIN memorizzato dovrei fare il contrario e trasformare in numero intero il pin ricevuto come sequenza di char dal decoder DTMF .. si potrei fare anche così ma in questo caso non potrei usare un pin composto sempre da 5 caratteri con degli zero iniziali..
insomma preferisco lavorare con le stringhe, in questa fase... non ho problemi di RAM...uso un 644


ma soprattutto che significa
Code: [Select]
intPIN = ((EEPROM.read(6)) | (EEPROM.read(7)<<8));  //legge il  PIN compreso tra 00000 e 65535 dalla eeprom;
in ogni cella della eeprom ci scrivi un byte, il numero del pin non supera certo il 255, perchè usi l'intero?

come detto sopra, uso due byte perchè ho deciso di usare un PIN composto da 5 cifre, compreso tra 0 e 65535 ... ok?

nonmmi sembra che ci siano errori di conversine di tipo di dato. .... comunque funziona bene. A parte la lettura del pin dalla eeprom che sto implementando adesso, tutto il resto sta funzionando ormai da qualche mese... prima il pin era misso in una variabile che dichiaravo all'inizio.. adesso la sto mettendo nella eeprom perchp sto implementando la fuznione che permette di cambiarla senza toccare il micro....con un comando via seriale che arriva da un'altro micro che si occupa dell'http.... ma questo è una'ltra storia.. adesso mi va benissimo che funzioni la lettura del pin dalla eeprom ed il relativo riconoscimento ..
ciao grazie..

ah tux... non ho capito bene quest'ultimo l'esempio che hai digitato per verificare errori di cast .. ma stasera appaena posso lo metto sull'IDE..
ri_ciao







tuxduino

L'esempio funziona così: se invio il carattere 'w' (per "write"), viene scritto un certo valore unsigned in in due locazioni  della EEPROM.
Se invece mando il carattere 'r' (per "read"), viene letto un unsigned int da quelle stesse locazioni.
La riga che legge la EEPROM e ricostruisce 'l'intero può essere scritta sia con che senza cast dei due byte letti ad unsigned int:

Code: [Select]

//return (((unsigned int)hiByte) << 8) | ((unsigned int)loByte);
    return EEPROM.read(indirizzo + 1) << 8 | EEPROM.read(indirizzo);


Ho notato che utilizzando l'una o l'altra riga il risultato è lo stesso, e cioè viene stampato correttamente il numero che è stato scritto in precedenza nelle due locazioni della EEPROM.

tuxduino

Veniamo alla questione  PIN in formato stringa o intero.

Il numero da indovinare lo scrivi in EEPROM sottoforma di unsigned int (ok, suddiviso in due byte, ma non c'entra) e non come stringa di 5 caratteri.
In ingresso invece leggi il numero da indovinare come sequenza di 5 caratteri.

Devi confrontare questi due dati, un unsigned int e una stringa di 5 caratteri.

Hai due strade:
- trasformare l'unsigned int in una stringa di 5 caratteri con zero-padding sinistro (come hai fatto) e confrontare tale stringa con quella fornita dall'utente, oppure
- trasformare la stringa in un unsigned int e confrontare il risultato di questa operazione con l'unsigned int letto dalla EEPROM.

Io credo che sia più semplice il secondo procedimento. L'unico problema è che una stringa che non codifichi per un numero intero (ad esempio perché contiene non-cifre), se sottoposta a atoi() produce 0. Quindi il PIN 00000 verrebbe "indovinato" da qualunque stringa non valida, oltre che da "00000".

pablos

Ahhh pin inteso come codice pin e vabbè allora ditelo!! :)
no comment

tuxduino

Non vorrei essere polemico, ma... bastava leggere:
Quote

PIN compreso tra 00000 e 65535 dalla eeprom


:)

Go Up