salve gente
una domanda al volo
che sappiate esiste una funzione di libreria (o almeno una cosa standard) che mi permette di invertire al volo una stringa (array di caratteri teminati da 0)?
io non ho trovato nulla, sembra essere un esercizio standard per le scuole, ma niente di libreria
beh, un po' ho cercato, ma dopo aver visto cose che voi umani........
ho deciso di scrivermela, e di mettermela nella mia libreria di "piccole funzioni utili"
char * invertistringa(char * stringa)
{
//inverte una stringa
byte i = 0;
byte j = strlen(stringa) - 1;
char c = 0;
while (i < j)
{
c = stringa[i];
stringa[i++] = stringa[j];
stringa[j--] = c;
}
return stringa;
}
formalmente restituisce un puntatore a carattere, ma in realtà punta alla stessa stringa di ingresso
volevo provare a fare lo swap senza una variabile temporanea, ma ho pensato che non ne vale la pena
come al solito, se ci vedete dei bacherozzi segnalatemelo, grazie
prossima idea: convertire dei float in stringhe in formato scientifico (esempio 1.234E3 significa 1234)
adesso ci apro un post
Standardoil:
ho deciso di scrivermela, e di mettermela nella mia libreria di "piccole funzioni utili"
Praticamente identica a come la avevo pensata (però io mi sono divertito a provarla in asm Z80, algoritmo identico anche se ovviamente a puntatori).
L'unica perplessità è il valore di ritorno, visto che comunque avviene una modifica in-place della stringa originale, a cosa serve un doppione del suo puntatore?
Lo swap senza variabile di appoggio però mi sembra meno efficiente, soprattutto se si usano indici invece di puntatori.
stringReverse(char * stringa)
{
char * i = stringa;
char * j = i + strlen(stringa) - 1;
while (i < j)
{
*i ^= *j;
*j ^= *i;
*i ^= *j;
i++;
j--;
}
}
MAIN LD HL,STRINGA
CALL REVERSE
RET
REVERSE PUSH HL
XOR A ; A = 0
LD BC,0
CPIR ; CERCA LO 0
EX DE,HL
DEC DE
DEC DE ; DE PUNTA ULTIMO BYTE
POP HL ; HL PUNTA PRIMO BYTE
LOOP LD B,H
LD C,L
AND A ; CARRY = 0
SBC HL,DE
RET NC ; FINE SE DE <= HL
LD H,B
LD L,C
LD B,(HL) ; SWAP
LD A,(DE)
LD (HL),A
LD A,B
LD (DE),A
INC HL
DEC DE
JP LOOP
Azz.... l'una e venti, sono stato colpito anche oggi dalla fascia delle bermuda....
Guardando implementazioni di funzioni stringa una volta sono stato colpito da una strreverse, che scorreva la stringa per metà, se il numero caratteri della stringa è pardi, diviso due fa due parti uguali, se i caratteri sono dispari si fa una divisione tra interi che restituisce solo la parte intera.
Un implementazione diversa che fa la stessa cosa. Esistono tante implementazioni quanti sono i programmatori
void inverti(char *s){
/* Questa funzione si basa che se il numero caratteri della stringa
sono pari diviso due fa due parti uguali, se i caratteri sono
dispari si tratta di una divisione tra interi per cui restituisce
solo la parte intera, e il carattere centrale della stringa non viene
modificato. Il vantaggio che cicla per metà della lunghezza della stringa. */
int len=strlen(s);
int i=0;
char tmp;
for(i=0;i<len/2;i++){// Cicla per metà caratteri della stringa
tmp=s[i];
s[i]=s[len-1-i];
s[len-1-i]=tmp;
}//end for
}// end function
Grazie a tutti e due,
per Claudio_ff
purtroppo io no asm, magari... ma non ho mai avuto occasione
bella la fascia oraria.. non la conoscevo
invece la ragione per la quale "restituisco" un puntatore a carattere è molto banale
per fare
Serial.print(invertistringa(s));
invece che
invertistringa(s);
Serial.print(s);
Sì, lo so: è una menata mia....
ma per me l'altra forma sarebbe un obbrobrio, non riucirei a scriverla, mi darebbe un fastidio fisico la tastiera sotto le dita
per lo swap senza variabile ausiliaria: intendevo truccare:
char * invertistringa(char * stringa)
{
//inverte una stringa
byte i = 0;
byte j = strlen(stringa) - 1;
byte l = j + 1; // riga aggiunta
// char c = 0; riga tolta
while (i < j)
{
stringa[l] = stringa[i]; // falsa variabile
stringa[i++] = stringa[j];
stringa[j--] = stringa[l]; // falsa variabile
}
stringa[l]=0;
return stringa;
}
per torn24
non ci avevo pensato al for dopo divisione
o forse lo avevo visto ma non ci avevo badato
in effetti mi fermo anch'io al centro della stringa, ma non faccio divisione, ma test esplicito
adesso non saprei quale sia piu' "rapida", magari qualcuno più bravo di me puo' indicarmelo
di nuovo grazie a tutti e due
Claudio_FF:
stringReverse(char * stringa)
{
char * i = stringa;
char * j = i + strlen(stringa) - 1;
while (i < j)
{
*i ^= *j;
*j ^= *i;
*i ^= *j;
i++;
j--;
}
}
No vabbè ma che figata! Sembra elegantissima ma ti giuro sto anche facendo delle prove e non capisco come funzioni la sostituzione dei caratteri all'interno del while!
Cioè ho capito che sostituisci l'ultimo col primo e così via, ma non capisco come faccia questa operazione a funzionare con lo xor :o
Io lo intuisco, ma non riesco a spiegarlo..
Reversibilità dello XOR (trucchi assembly PIC per risparmiare righe/memoria/registri):
VAR_A VAR_B
-----------------
A B
VAR_A ^= VAR_B A^B B
VAR_B ^= VAR_A A^B A <--- B ^ A^B = A
VAR_A ^= VAR_B B A
^
|
A^B ^ A = B ---'
invece la ragione per la quale "restituisco" un puntatore a carattere è molto banale
Ah, ok, per usarla in modo funzionale... approvato 8)
Standardoil:
invece la ragione per la quale "restituisco" un puntatore a carattere è molto banale
Non vorrei dire una caxxata, ma anche molte funzioni di libreria, anche se modificano la stringa di un parametro, comunque ne fanno anche il ritorno con return. Mi pare.
...azz... la magia dello XOR !!
65 e 71 65 xor 71 = 6 71 xor 6 = 65 65 xor 6 = 71 !!
Claudio_FF:
Reversibilità dello XOR (trucchi assembly PIC per risparmiare righe/memoria/registri):VAR_A VAR_B
-----------------
A B
VAR_A ^= VAR_B A^B B
VAR_B ^= VAR_A A^B A <--- B ^ A^B = A
VAR_A ^= VAR_B B A
^
|
A^B ^ A = B ---'
Fantastico, grazie mille
Grazie anche da parte mia
Intuivo, prima
Adesso è chiaro