2010-08-30 8 views
5

Vorrei confrontare un carattere letterale con il primo elemento di corda, per verificare la presenza di commenti in un file. Perché usare un char? Voglio farlo in una funzione, che accetta un carattere var per il commento. Non voglio permettere una stringa perché voglio limitare a un singolo carattere di lunghezza.Confrontando carattere letterale di std :: string in C++

Con questo in mente ho assunto il modo più semplice per andare sarebbe quello di affrontare il carattere e passare alla funzione confrontare la std :: della stringa. Tuttavia questo mi sta dando risultati non voluti.

Il mio codice è il seguente:

#include <string> 
#include <iostream> 

int main (int argc, char *argv[]) 
{ 
    std::string my_string = "bob"; 
    char my_char1 = 'a'; 
    char my_char2 = 'b'; 

    std::cout << "STRING : " << my_string.substr(0,1) << std::endl 
     << "CHAR : " << my_char1 << std::endl; 
    if (my_string.substr(0,1).compare(&my_char1)==0) 
    std::cout << "WOW!" << std::endl; 
    else 
    std::cout << "NOPE..." << std::endl; 

    std::cout << "STRING : " << my_string.substr(0,1) << std::endl 
     << "CHAR : " << my_char2 << std::endl; 
    if (my_string.substr(0,1).compare(&my_char2)==0) 
    std::cout << "WOW!" << std::endl; 
    else 
    std::cout << "NOPE..." << std::endl; 

    std::cout << "STRING : " << my_string << std::endl 
     << "STRING 2 : " << "bob" << std::endl; 
    if (my_string.compare("bob")==0) 
    std::cout << "WOW!" << std::endl; 
    else 
    std::cout << "NOPE..." << std::endl; 
} 

Mi dà ...

STRING : b 
CHAR : a 
NOPE... 
STRING : b 
CHAR : b 
NOPE... 
STRING : bob 
STRING 2 : bob 
WOW! 

Perché la funzione pensano che il sub-string e carattere non sono gli stessi. Qual è il modo più breve per confrontare correttamente char e std :: string vars?

(una breve concione per evitano riclassificazione della mia domanda .... sentitevi liberi di saltare)
quando dico più breve voglio dire che da un desiderio per la codifica eloquenza. Si prega di notare, questa NON è una domanda a casa. Sono un dottorando in ingegneria chimica candidato e sto codificando come parte della ricerca indipendente. Una delle mie ultime domande sono stati riclassificati come "compiti a casa" dall'utente msw (che ha anche fatto una battuta sprezzante) quando ho chiesto di efficienza, che ho considerato al confine di abuso. Il mio codice può o non può essere riutilizzato da altri, ma sto cercando di rendere più facile da leggere e gestibile. Ho anche un bizzarro desiderio di rendere il mio codice il più efficiente possibile, ove possibile. Da qui le domande sull'efficienza e l'eloquenza.

risposta

14

Fare questo:

if (my_string.substr(0,1).compare(&my_char2)==0) 

non funzionerà perché si sta "ingannando" la stringa a pensare che sta ottenendo un puntatore a una C-string terminata da null. Questo avrà effetti strani fino al crash del tuo programma. Invece, basta usare uguaglianza normale per confrontare il primo carattere della stringa con my_char:

if (my_string[0] == my_char) 
    // do stuff 
+5

E non dimenticare di controllare '0

3

È possibile utilizzare l'operatore [] di spago per confrontare ad un singolo carattere

// string::operator[] 
#include <iostream> 
#include <string> 
using namespace std; 

int main() 
{ 
    string str ("Test string"); 
    int i; char c = 't'; 
    for (i=0; i < str.length(); i++) 
    { 
     if (c == str[i]) { 
      std::cout << "Equal at position i = " << i << std::endl; 
     } 
    } 
    return 0; 
} 
1

Il comportamento delle prime due chiamate da confrontare dipende interamente su ciò che il contenuto della memoria casuale segue l'indirizzo di ogni char. Si sta chiamando basic_string::compare(const char*) e si presume che il parametro qui sia un C-String (terminato da null), non un singolo carattere. La chiamata confrontare() confronterà il tuo personaggio desiderato, seguito da tutto nella memoria dopo che char fino al prossimo byte 0x00, con lo std :: string in mano.

Otoh l'< < l'operatore ha un sovraccarico corretto per l'input di char in modo che l'output non rifletta ciò che si sta effettivamente confrontando qui.

Converti i decli di e b in const char[] a = "a"; e otterrai ciò che desideri.

4

Perché non utilizzare semplicemente l'operatore di indicizzazione sulla stringa? Restituirà un tipo di carattere.

if (my_string[0] == my_char1) 
1

Piuttosto standard, le stringhe in C++ sono terminate con null; i personaggi non lo sono.Quindi, usando il metodo di confronto standard, stai veramente controllando se "b \ 0" == 'b'.

ho usato questo e ottenuto il risultato desiderato:

if (my_string.substr(0,1).compare(0, 1, &my_char2, 1)==0) 
    std::cout << "WOW!" << std::endl; 
else 
    std::cout << "NOPE..." << std::endl; 

Ciò sta dicendo è iniziare alla posizione 0 della sottostringa, utilizzare una lunghezza di 1, e confrontarlo con il mio riferimento di carattere con una lunghezza di 1. Reference

+1

Le stringhe in C++ NON terminano con null. Sono terminati con null in C, perché in realtà sono un puntatore al char. –

+0

@Draco: 'non è necessario che' std :: string' sia terminato da null (anche se questo sta cambiando in 0x), ma ci sono ancora molti posti nello standard C++ che presuppongono una matrice di char terminata da null. Compreso un numero di metodi all'interno di 'std :: string', come illustra questa domanda. –

Problemi correlati