Funzione di confronto array char

Una su tutte strncmp confronta le stringhe ma da li in poi si apre un mondo di funzioni che copiano stringhe, parti di esse, ecc. ecc.

Docdoc, mi spieghi meglio come funziona quella riga stato &= (a[i]==b[i]);???
Secondo te/voi,(a parte la lettera maiuscola minuscola, di cui non sapevo) è giusto come ho scritto la funzione?? Nel senso, durante il ciclo for, appena trova una divergenza nel char,cambia valore la variabile e si interrompe con break....(scusate davvero l'ignoranza)....

fabpolli, ho guardato il link che mi hai messo....c'è un mondo, ma parla sempre di stringhe e libreria string.h...tranne che per strncmp che è comparazione dei caratteri delle due stringhe, proprio come voglio io....Ecco il mio dubbio è sempre quello: ma non si dice di evitare la libreria string.h??

manolomao:

stato &= (a[i]==b[i]);

E' l'operatore booleano su bit in questo caso l'AND sul bit, essendo stato booleano e quindi composto da un solo bit è come fare:

stato = stato && a[i]==b[i];

quando parti valorizzi stato a true (Che equivale a 1), man mano che confronti la stringa fai l'and sul bit tra stato e il confronto che che è uguale vale 1 quindi 1 and 1 da 1 ma se un carattere in una certa posizione è differente avrai 1 and 0 che da zero e da quel momento in poi qualiasi siano i caratteri successivi stato resterà a zero (and tra zero e zero o uno darà sempre zero) quindi la funzione restituirà false
Rispetto a quanto hai scritto tu la funzione di docdoc scansioen sempre tutta la stringa, mentre la tua esce alla prima occorrenza di un carattere differente, per fare la medesima cosa con la forma di docdoc puoi fare:

bool confronta(char *a, char *b, byte k){  // Confronta(primo array,secondo array,numero dei char da confrontare)
  bool stato = true;
  for (byte i=0; stato  && i<k;i++)
    stato &= (a[i]==b[i]);
  return(stato);
}

oppure con una forma meno compatta

bool confronta(char *a, char *b, byte k){  // Confronta(primo array,secondo array,numero dei char da confrontare)
  bool stato = true;
  for (byte i=0; i<k;i++)
  {
    stato &= (a[i]==b[i]);
    if(!stato)
    {
       break;
    }
  }
  return(stato);
}

oppure ancora

bool confronta(char *a, char *b, byte k){  // Confronta(primo array,secondo array,numero dei char da confrontare)
  bool stato = true;
  byte i=0 
  while (stato && i<k)
  {
    stato &= (a[i]==b[i++]);
  }
  return(stato);
}

manolomao:
fabpolli, ho guardato il link che mi hai messo....c'è un mondo, ma parla sempre di stringhe e libreria string.h...tranne che per strncmp che è comparazione dei caratteri delle due stringhe, proprio come voglio io....Ecco il mio dubbio è sempre quello: ma non si dice di evitare la libreria string.h??

E' un tranello in cui si casca facilmente la libreria standard C string.h è corretto usarla lavora solo ed esclusivamente su array di char è la classe String che va evitata come la peste, la prima è una libreria di funzioni la seconda è appunto una classe che ha i difetti ormai noti su MCU senza garbage collector

ottimo, ed io ci casco....
Quindi tutte le funzioni riportate in quel link le posso usare senza paura,giusto?

Esatto, in realtà per essere più precisi puoi usare tutte le funzioni definiti nel file string.h presente nella cartella d'installazione dell'IDE di Arduino, potrebbe esserci alcune differenze rispetto al sito di cui ho messo il link, con il file include vai sul sicuro

fabpolli:
E' l'operatore booleano su bit in questo caso l'AND sul bit, essendo stato booleano e quindi composto da un solo bit è come fare:

Hehehe, hai perfettamente descritto ciò che avrei spiegato io. Mi hai risparmiato la fatica, grazie! :smiley:

fabpolli:
E' l'operatore booleano su bit in questo caso l'AND sul bit, essendo stato booleano e quindi composto da un solo bit è come fare:

stato = stato && a[i]==b[i];

quando parti valorizzi stato a true (Che equivale a 1), man mano che confronti la stringa fai l'and sul bit tra stato e il confronto che che è uguale vale 1 quindi 1 and 1 da 1 ma se un carattere in una certa posizione è differente avrai 1 and 0 che da zero e da quel momento in poi qualiasi siano i caratteri successivi stato resterà a zero (and tra zero e zero o uno darà sempre zero) quindi la funzione restituirà false
Rispetto a quanto hai scritto tu la funzione di docdoc scansioen sempre tutta la stringa, mentre la tua esce alla prima occorrenza di un carattere differente, per fare la medesima cosa con la forma di docdoc puoi fare:

bool confronta(char *a, char *b, byte k){  // Confronta(primo array,secondo array,numero dei char da confrontare)

bool stato = true;
 for (byte i=0; stato  && i<k;i++)
   stato &= (a[i]==b[i]);
 return(stato);
}



oppure con una forma meno compatta


bool confronta(char *a, char *b, byte k){  // Confronta(primo array,secondo array,numero dei char da confrontare)
 bool stato = true;
 for (byte i=0; i<k;i++)
 {
   stato &= (a[i]==b[i]);
   if(!stato)
   {
      break;
   }
 }
 return(stato);
}



oppure ancora


bool confronta(char *a, char *b, byte k){  // Confronta(primo array,secondo array,numero dei char da confrontare)
 bool stato = true;
 byte i=0
 while (stato && i<k)
 {
   stato &= (a[i]==b[i++]);
 }
 return(stato);
}

Grazie,sempre molto gentile e chiaro!!
Grazie a voi ho imparato qualcosa in più...

Un consiglio :slight_smile: delle varie funzioni stringa del C si trovano implementazioni online, si trovano dei sorgenti online. Basta fare ricerche del tipo "strncmp() source code" o "strcmp implementation in c", visionarle è una cosa molto istruttiva, ti insegna a operare con le stringhe nel modo migliore e COSA INTERESSANTE
ti mostra che per uno stesso risultato i programmatori si "inventano" soluzioni diverse, quindi trovi tante soluzioni a uno stesso problema :slight_smile:

Grazei a tutti per i consigli, funziona alla grande e credo di aver imparato qualcosa in più...
PS @Docdoc, perchè non usare una const char all'interno della funzione??

Come ho detto esistono diverse soluzioni per uno stesso problema! Ci sono soluzioni migliori di altre, la soluzione mostrata da docdoc è migliore di quello che volevi fare tu :slight_smile:

Però anche il tuo approccio è una possibile soluzione, solo con qualche modifica

  1. confronto carattere per carattere
  2. se trovo uno diverso restituisco 0
  3. se tutti i caratteri sono uguali restituisco 1

Tua funzione modificata

boolean Confronta( char*a, char*b,byte k){  
 
     for (byte i=0;i<k;i++){
         if (a[i]!=b[i])
             return false; // ho trovato un carattere diverso
     }

     return true; //il ciclo for è terminato non è uscito dalla funzione quindi tutti i carattere sono uguali
 
}

Per pura curiosità sono andato a vedere l'implementazione della strncmp
È pura poesia...

manolomao:
PS @Docdoc, perchè non usare una const char all'interno della funzione??

Generalmente non uso le const, ma in questo caso non dovendo cambiare nulla delle stringhe puoi anche usare const.

E dove la metteresti la const?
Quello che passi alla funzione e il puntatore alla stringa, non la stringa
Puntatore può anche essere costante, ma la stringa no....

Forse ho scritto una caxella
Magari stasera ci guardo bene

Mi hai fatto venire il dubbio perché const non l'ho mai usato :slight_smile:
Ho provato su ideone un ide online, e se usi const su un puntatore a char rende immodificabile la stringa.

P.S. non uso mai const nei parametri di una funzione, sono io che scrivo la funzione e sono io che so che non vanno modificati i parametri :wink: quindi lo trovo inutile :slight_smile: :slight_smile:

Si infatti
Const char * è costante la stringa
Char const * è costante il puntatore
Const char const * è puntatore costante a stringa costante
Comunque sono d'accordo con te: io scrivo la funzione, io evito di scrivere dove non devo...

Se devi fare una API per qualcun altro, difficilmente lui sa cosa può modificare e cosa no, da cui l'utilità di const.

Senza contare che il compilatore può mettere in atto varie ottimizzazioni, se sa che qualcosa non deve essere modificato (anche se i compilatori più furbi sono in grado di accorgersene da soli).

Infine, in C++ sono valide entrambe le espressioni:

const char *pippo;
char * const pippo;

Il primo vuol dire che ciò a cui il puntatore punta non è modificabile, il secondo che il puntatore stesso non è modificabile (ma ciò a cui punta sì).

Le due cose possono anche essere combinate, ottenendo un fantastico:

const char * const pippo;

Che ho pure usato da qualche parte in Webbino...