2017-04-14 6 views
0

Ich benutze gcc in Ubuntu14. Hier ist mein Code: (test.c)Falsche Ausgabe von argv?

#include <stdio.h> 
int main(int argc, char *argv[]){ 
int i=0; 
for(i=1; i <argc;i++) 
{ 
    if (argv[i] = "xx") { 
     printf("I got you!\n"); 
    } 
printf("%d %s\n",i, argv[i]); 
} 
return 0; 
} 

ich kompilieren und diesen Code ausführen mit:

gcc test.c -o test 

./test aa bb xx

Ich erwarte, dass der Ausgang

1 aa 
2 bb 
I got you! 
3 xx 

zu sein Aber es kommt mit

heraus 0
I got you! 
1 xx 
I got you! 
2 xx 
I got you! 
3 xx 

auch wenn ich ./test aa bb die Ausgabe

I got you! 
1 xx 
I got you! 
2 xx 

Ich weiß nicht, warum immer die Ausgabe mit „xx“ herauskommt, ist es jemand geben Sie mir einen Hinweis, bitte?

+0

Falscher Kompilierbefehl. Sie sollten 'gcc -Wall -g test.c -o testprog' verwenden (Sie möchten alle Warnungen '-Wall' und Debug-Info '-g' !!) dann ** den Debugger verwenden **' gdb testprog' –

+1

Sie können vergleiche Zeichenfolgen in C nicht mit dem Operator '==' (den Sie nicht verwenden), sondern müssen den Befehl 'strcmp' verwenden (http://en.cppreference.com/w/c/string/byte/ strcmp) -Funktion. –

Antwort

4

Was Sie eigentlich hier tut, ist die Zuordnung "xx" zu argv[i] und dann Verzweigung auf Ergebnis dieser Zuordnung. Dies liegt daran, dass der Operator = für die Zuweisung zuständig ist. Wenn Testen (d. H. Vergleichen) ein Wert müssen Sie den Operator für die Gleichheit verwenden, die == ist.

Auch Strings können auf diese Weise nicht verglichen werden, da sie keinen primären Datentyp haben wie in einigen anderen Sprachen. Wenn Sie if (argv[i] == "xx") versuchten, würden Sie die Adresse des ersten Zeichens jeder der Zeichenfolgen vergleichen, die noch falsch waren!

Um dies zu lösen, können wir die strcmp() Funktion verwenden, die den Inhalt von zwei Strings vergleicht und ein Ergebnis ungleich null zurückgibt, wenn die Strings unterschiedlich sind. Die strcmp()-Funktion wird von der Header-Datei string.h zur Verfügung gestellt.

Um das gewünschte Ergebnis zu erzielen, fügen Sie #include <string.h> oben in der Datei ein und verwenden Sie if (strcmp(argv[i], "xx") == 0).

Siehe this Tutorials Point page für weitere Informationen über strcmp()

+0

Danke @Toby. – link5555

+1

@ link5555 Gern geschehen. FYI, wenn Sie SO neu sind: Wenn eine Antwort (muss nicht meins sein) Ihr Problem löst, sollten Sie das Häkchen daneben klicken, damit die Frage als beantwortet erscheint. – Toby

0

a) da = keinen Vergleich hat aber einen Auftrag

b) erhielten Sie eine String-Vergleichsfunktion verwenden (== würde nicht funktionieren entweder für sie)

1

Zwei Probleme mit if (argv[i] = "xx"):

  1. Sie den Zuweisungsoperator und es macht argv[i] Punkt zum Stringliteral "xx". Und da die Adresse des String-Literals immer nicht NULL ist, ist die Bedingung immer wahr.

    Sie wollten wahrscheinlich den Gleichheitsoperator == verwenden. Aber dann wird es immer noch nicht funktionieren. Siehe Punkt 2 unten.

  2. Mit ==, Sie überprüfen, ob argv[i][0] ‚s Speicherplatz die gleiche wie die des ersten Zeichens von "xx" ist (Dies aufgrund geschieht Array‚Zerfall‘, Google it). Das ist nicht was du willst.

    Sie möchten den Inhalt von argv[i] mit dem Zeichenfolgenliteral vergleichen. So verwendet strcmp von string.h:

    if (strcmp(argv[i], "xx") == 0) 
    
1

In dieser Erklärung

if (argv[i] = "xx") { 
      ^^^ 

die Adresse des ersten Zeichens des Stringliteral "xx" den Zeiger argv[i] zugeordnet ist. Da der Wert der Adresse ungleich 0 ist, ist dieser Ausdruck immer wahr.

jedoch, wenn Sie

if (argv[i] == "xx") { 
      ^^ 

schreiben, dann wird es im Vergleich zwei Adressen: die Adresse der entsprechenden Benutzer gelieferten Parameter und die Adresse der Stringliteral (Adressen ihrer ersten Zeichen). Als Ergebnis wird der Ausdruck immer falsch ergeben.

Sie müssen Zeichenfolgen vergleichen, auf die diese Zeiger zeigen. So sollten Sie schreiben

#include <stdio.h> 
#include <string.h> 

int main(int argc, char *argv[]) 
{ 
    int i = 0; 

    while (++i < argc) 
    { 
     if (strcmp(argv[i], "xx") == 0) 
     { 
      printf("I got you!\n"); 
     } 

     printf("%d %s\n", i, argv[i]); 
    } 

    return 0; 
} 
+0

"_der Ausdruck liefert immer false_" - Ist es wegen String-Pooling nicht möglich, dass er wahr ist? Das heißt, angenommen "argv [i]' zeigt auf "" xx "' –

+0

@CoolGuy Das ist unmöglich, weil String-Literale zur Kompilierzeit statische Speicherdauer haben und nicht modifizierbar sind, während vom Benutzer bereitgestellte Parameter zur Laufzeit zugewiesen werden und modifizierbar. –