2010-08-30 10 views
5

Ich möchte ein Zeichen Literal mit dem ersten Element von Zeichenfolge vergleichen, um nach Kommentaren in einer Datei zu überprüfen. Warum ein Char benutzen? Ich möchte dies zu einer Funktion machen, die eine Zeichenvariable für den Kommentar akzeptiert. Ich möchte keine Zeichenkette zulassen, weil ich sie auf ein einzelnes Zeichen beschränken möchte.Vergleichen von Zeichen Literal mit Std :: String in C++

In diesem Sinne nahm ich an, der einfache Weg zu gehen wäre, das Zeichen zu adressieren und es an die Vergleichsfunktion von std :: string zu übergeben. Dies führt jedoch zu unbeabsichtigten Ergebnissen.

Mein Code ist wie folgt:

#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; 
} 

mich gibt ...

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

Warum denkt die Funktion der Unterkette und Zeichen sind nicht die gleichen. Was ist der kürzeste Weg, um chars und std :: string vars richtig zu vergleichen?

(ein kurzer Wortschwall vermeiden Neueinstufung meiner Frage .... fühlen Sie sich frei zu überspringen)
Als ich kürzest sage, meine ich, dass für aus dem Wunsch Beredsamkeit Codierung. Bitte beachten Sie, dies ist KEINE Hausaufgabenfrage. Ich bin promovierter Chemieingenieur und studiere als Teil der unabhängigen Forschung. Eine meiner letzten Fragen wurde vom Benutzer msw (der auch eine abfällige Bemerkung gemacht hat) als "Hausaufgabe" eingestuft, als ich nach Effizienz fragte, die ich an der Grenze des Missbrauchs betrachtete. Mein Code wird möglicherweise von anderen wiederverwendet, aber ich versuche, ihn leserlich und wartbar zu machen. Ich habe auch ein bizarres Verlangen, meinen Code soweit wie möglich so effizient wie möglich zu machen. Daher die Fragen nach Effizienz und Eloquenz.

Antwort

14

dies zu tun:

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

funktioniert nicht, weil Sie „austricksen“ die Zeichenfolge sind zu denken, dass es einen Zeiger auf eine Null-beendete C-Schnur erhält. Dies wird bis zum Absturz Ihres Programms seltsame Auswirkungen haben. Stattdessen nur normale Gleichheit verwenden, um die ersten Zeichen des Strings mit my_char zu vergleichen:

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

Und vergessen Sie nicht, überprüfen Sie das <0

3

können Sie den Operator [] der Zeichenkette, die es zu einem einzelnen Zeichen vergleichen

// 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

Das Verhalten der beiden ersten Anrufe ist völlig davon abhängig, zu vergleichen, was zufällige Speicherinhalt folgt die Adresse jedes Zeichen. Sie rufen 10 an und der Parameter wird hier als C-String (nullterminiert) angenommen, nicht als ein einzelnes Zeichen. Der Aufruf compare() vergleicht Ihr gewünschtes Zeichen gefolgt von allem, was sich im Speicher befindet, nach dem Zeichen bis zum nächsten Byte 0x00, wobei die Zeichenfolge std :: in der Hand liegt.

Otoh der < < Operator hat eine korrekte Überladung für char Eingabe, so dass Ihre Ausgabe nicht widerspiegelt, was Sie hier tatsächlich vergleichen.

Konvertieren Sie die Werte von und b in const char[] a = "a"; und Sie erhalten, was Sie wollen.

4

Warum nicht einfach den Indexierungsoperator auf Ihrer Zeichenfolge verwenden? Es wird ein Char-Typ zurückgegeben.

1

Ziemlich Standard, Zeichenfolgen in C++ sind Null-terminiert; Zeichen sind nicht.Mit der Standardvergleichsmethode überprüfen Sie also, ob "b \ 0" == 'b'.

benutzen ich diese und bekam die gewünschte Ausgabe:

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

Was ist an der Position 0 des Teils beginnen zu sagen, eine Länge von 1 verwenden, und vergleichen Sie sich mit einer Länge meines Charakter Bezug von 1. Reference

+1

Strings in C++ sind NICHT nullterminiert. Sie sind in C null-terminiert, weil sie eigentlich ein Zeiger auf char sind. –

+0

@Draco: 'std :: string' muss nicht nullterminiert sein (obwohl sich das in 0x ändert), aber es gibt immer noch viele Stellen im C++ - Standard, die ein nullterminiertes Array von char annehmen. Einschließlich einer Reihe von Methoden in 'std :: string', wie diese Frage veranschaulicht. –