2009-11-23 19 views
25

Sto cercando di compilare il seguente molto molto semplice pezzo di codice sorgente:g ++ di errore: 'stricmp' non è stato dichiarato in questo ambito (ma OK per 'strcmp')

#include <cstring> 
// #include <string.h> 
// using namespace std; 

class Helper { 
public: 
    int cStringsAreEqual(const char *s1, const char *s2) { 
     return stricmp(s1, s2); 
    } 
}; 

... ma io ricevo il seguente messaggio di errore:

g++ error: ‘stricmp’ was not declared in this scope 

Tuttavia quando uso strcmp() al posto districmp() allora tutto va bene!

Cosa può esserci di sbagliato qui? Non dovrebbe essere permesso stricmp() quando strcmp() è permesso?

Sureley, tutto questo potrebbe essere scritto in un modo molto migliore senza utilizzare strcmp/stricmp.

Ma non è questo il punto.

Sto eseguendo il porting di un pezzo di software, che utilizza molto le chiamate a stricmp(). E se in qualche modo possibile vorrei evitare tutti gli sforzi necessari per cambiare ogni chiamata a stricmp.

Qualsiasi aiuto su questo sarebbe molto apprezzato!

BTW: Sto usando Ubuntu karmic OS (v9.10) con g ++ v4.4.1.

BTW: come potete vedere ho anche fatto alcune prove con "#include string.h" o con "namespace std" ma nulla è servito.

+0

Considerando che stricmp e strcmp non sono gli stessi (quest'ultimo è case sensitive), si potrebbe desiderare di hesistate prima di cambiare loro comunque. – Brian

+2

I * so * che non sono uguali. Ecco perché voglio usare stricmp e non strcmp –

+0

Nota anche che '' e '' non sono esattamente gli uni. Non è la causa del tuo problema, ma dovrai scrivere 'std :: strcmp' (o' std :: strcoll') piuttosto che assumere che i nomi siano importati nello spazio dei nomi globale. –

risposta

34

Prova strcasecmp(). Ecco il manual page per questo. È conforme a 4.4BSD e POSIX.1-2001.

+0

Questa sarebbe un'opzione.strcasecmp() sembra avere gli stessi parametri. Quindi non dovrebbe essere difficile creare un piccolo script perl che faccia un cambiamento globale. Molte grazie! –

+0

Nessun problema. Dai anche un'occhiata al commento di Mark Rushakoff su come le impostazioni locali influenzano questa funzione. – Gonzalo

+1

Attenzione che strcasecmp dipende dalla tua localizzazione. Quindi strcasecmp ("div", "DIV") NON restituirà 0 in una locale turca (la I minuscola è ı). Ciò significa che importa da dove proviene la tua stringa :-(. Ci sono altri esempi in altre lingue.Potresti interrompere il tuo programma per gli utenti stranieri. – rockdaboot

13

stricmp is neither POSIX nor ANSI, quindi non importa se strcmp è consentito, se il compilatore o la libreria standard è strettamente aderente alle funzioni di libreria standard POSIX o ANSI (come è probabilmente il caso con la suite GCC).

+0

esiste un'alternativa POSIX/ANSI con la stessa semantica? –

+3

È complicato, perché l'idea di "distinzione tra maiuscole e minuscole" può dipendere dalle impostazioni locali o dal sistema operativo. Vedi alcune delle risposte in questa domanda: http://stackoverflow.com/questions/11635/case-insensitive-string-comparison-in-c –

+0

Sto usando Eclipse CDT su Windows 7 con Cygwin e qui viene accettato stricmp. Sulla mia macchina Linux, con GCC non è accettato. Ciò significa che il compilatore incluso con Cygwin NON è POSIX o ANSI? –

10

Aggiungi un define per sovrascrivere stricmp con strcasecmp sulle piattaforme che stai cercando.

#ifdef _IPHONE <- your platform define here 
#define stricmp strcasecmp 
#define strnicmp strncasecmp 
#endif 

Quindi è possibile utilizzare semplicemente stricmp sempre.

+0

Ho avuto lo stesso errore e l'ho risolto con successo. –

+0

dove lo mettiamo –

+0

Basta inserirlo in un'intestazione o nella parte superiore con qualsiasi altra direttiva preprocessore (ifdefs/define): http://www.cplusplus.com/doc/tutorial/preprocessor/ #define _IPHONE passerebbe all'utilizzo precedente meno il " <- .. "parte" –

-1

Abbastanza facile da fare il vostro proprio se necessario ...

int my_stricmp (const char *s1, const char *s2) 
{ 
    while (*s1 != 0 && *s2 != 0) 
    { 
     if (*s1 != *s2 && ::toupper (*s1) != ::toupper(*s2)) 
     { 
      return -1; 
     } 
     s1++; 
     s2++; 
    } 
    return (*s1 == 0 && *s2 == 0) ? 0 : -1; 
} 
+0

Come restituisce un valore positivo quando 's1' ordina più tardi di' s2'? O è destinato ad avere un'interfaccia diversa da 'std :: strcmp()'? –

+0

Problema indirizzato @TobySpeight indicato anche in logica –

+1

'CAVEAT': le chiamate a' :: toupper' sono specifiche della locale. Potresti ottenere risultati diversi a seconda di dove lo esegui. anziché. –

Problemi correlati