wake-up-neo.net

Wie kann man Argumente aus der Hauptfunktion in C drucken?

Ich habe gerade gelernt, dass wir zwei Hauptargumente in die Hauptfunktion "argc" und "argv" eingeben können. Allerdings kann ich nicht verstehen, was argv in diesem Zusammenhang ist: int main(int argc, char* argv[]); 

Ist argv ein Array von Zeichen? oder ist es ein Array von Zeigern, die auf Zeichen zeigen? Auf jeden Fall suche ich nach einer Möglichkeit, die Argumente auszudrucken, die der Benutzer an dieses Programm übergibt. Dies ist der Code, den ich geschrieben habe, aber er druckt nicht sozusagen die Argumente. Was ist daran falsch? Ich denke, es ist mein Verständnis von argv, das diesen Code falsch macht. 

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

Nach den Vorschlägen, die ich aus Antworten erhielt, habe ich meinen Code wie folgt korrigiert.

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

Ich verwende Ubuntu Linux in VMWare auf meinem Windows 8.1-PC. Dies ist die Ausgabe, die ich bekomme. Es wird nur Argc gedruckt und danach nichts mehr. Was ist das Problem? Ist es so, wie ich es kompiliere oder so etwas in Linux-Terminal?

 The snapshot of my terminal

In der obigen Abbildung möchte ich, dass die Zahlen 2, 4, 5, 3 erneut gedruckt werden, sie werden jedoch nicht gedruckt. 

Vielen Dank.

9
user5987642

Lassen Sie uns die Dinge Schritt für Schritt erklären. Zunächst einmal, wenn Sie Ihr Programm aufrufen, indem Sie Folgendes aufrufen:.

./my-program arg0 arg1 arg2

Du gibst eine Reihe von drei Argumenten, richtig? Und jedes Argument ist eine Zeichenfolge, richtig? Nun kann die main-Funktion einen von zwei Prototypen haben, wie vom C-Standard festgelegt ...

int main(); // Let's not worry about this for now
int main(int argc, char **argv);

Die Idee ist, dass main die von Ihnen angegebenen Argumente verarbeiten kann. argc gibt die Anzahl der Argumente an. Wenn Sie drei Argumente übergeben haben, ist argc 4! Dies geschieht, weil ein erstes Argument vor allen anderen ./my-program übergeben wird und Ihr Programm sich selbst erkennen lässt.

Was bedeutet char **argv? Etwas von der Form X* ist ein Zeiger auf X, richtig? char * ist also ein Zeiger auf char und char ** ist ein Zeiger auf char. In C ist eine Zeichenfolge einfach ein nullterminiertes Array von char, und ein Array kann zu einem Zeiger "degradiert" werden. Dies bedeutet, dass argv ein Array von Strings ist, von denen argv[0] der erste Name des Programms ist.

Mit dem C-Standard können Sie jetzt jeden "kompatiblen" Prototyp für main schreiben. Zum Beispiel können Sie eines davon schreiben ...

int main(int argc, const char *const argv[]);
int main(int argc, const char *argv[])
int main(int argc, const char **argv);
int main(int argc, const char *const *const argv);

Sie müssen jetzt nicht verstehen, was sie alle bedeuten, nur dass argv ein Array von Strings ist und dass Sie niemals / Strings modifizieren sollten, da der ursprüngliche main-Prototyp Ihnen zu vertrauen scheint. Wenn Sie wissen, dass die Argumente mit argv[1] beginnen, wird Ihr Code ...

for(i=0;i<argc-1;i++)

Bedeutet: "Für jede i im Bereich von 0 bis argc - 1".

    printf("%s",*argv[i]);

Bedeutet: "Das erste Zeichen des ith Elements von argv ausgeben". Warum wäre das falsch? Zunächst drucken Sie eine char und sagen printf, dass es sich um eine Zeichenfolge handelt. Dies hat undefiniertes Verhalten . Dann durchlaufen Sie die ersten ith-Elemente von argv. Dies bedeutet, dass das erste "Nicht-Argument" -Element in die Mischung einbezogen wird und das letzte Argument nicht. Um es zu lösen, schreibe etwas wie ...

for(i = 1; i < argc; i++)

Bedeutet: "Für jede i im Bereich von 1 bis argc".

    printf("%s", argv[i]);

Bedeutet: "Das ith Element von argv auf stdout drucken.

9
3442

Ist argv ein Array von Zeichen? oder ist es ein Array von Zeigern, die auf Zeichen zeigen? 

argv ist ein Zeiger auf char. Wenn eine Liste von Argumenten durch die Befehlszeile übergeben wird, wird ein Array von char-Zeigern erstellt, und jeder dieser Zeiger zeigt auf jedes dieser Argumente, die in Form von Zeichenfolgen zusammen mit dem Programmnamen gespeichert werden. argv zeigt auf den ersten Zeiger dieses char *-Arrays. Daher ist argv[i] ein Zeiger auf char

                           +--------------------------+
              +----+  +--> | argument 1 (program name)|
argv[0]+----> |    |  |    +--------------------------+
              |  +----+
              +----|       +--------------------------+
              |  +-------> |       argument 2         |
              |    |       +--------------------------+
              +----+
              |  +----+    +--------------------------+
              |    |  +--> |       argument 3         |
              +----+       +--------------------------+
           "char *" array

Du musst dich ändern 

printf("%s",*argv[i]);  

zu 

printf("%s",argv[i]);  

*argv[i] ist vom Typ char. %s erwartet einen Typ von char *.

5
haccks

In Ihrer bearbeiteten Frage haben Sie Ihr Hauptproblem behoben. Beachten Sie nun, dass Ihre Eingabeaufforderung aussieht

./[email protected]:~/test$

Hier ist ./mygrep245 Ihre Ausgabe, nachdem Sie "5\n" gedruckt haben. Sie haben vergessen, Zeilenvorschübe zu drucken, daher wurden die gesamte Ausgabe und die nachfolgende Shell-Ausgabe unverändert verkettet. Das letzte Argument 3 wurde nicht gedruckt, weil Sie i<argc-1 anstelle von i<argc oder i<=argc-1 in Ihre Schleifenbedingung einfügen.

2
Ruslan

char *argv[] ist ein Zeiger auf Zeiger auf char, da Arrays in Funktionsargumenten automatisch in Zeiger umgewandelt werden, die auf Elemente des Arrays zeigen.

Sie haben undefiniertes Verhalten aufgerufen, indem Sie Daten mit einem falschen Typ an printf(): %s übergeben, der char* erwartet, aber char übergeben wurde (für Variablenvariablenargumente in int konvertiert).

Entfernen Sie den zusätzlichen *, um den Zeiger zu dereferenzieren.

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

Möglicherweise möchten Sie auch i<argc anstelle von i<argc-1. Warum drucken Sie nicht das letzte Argument aus?

1
MikeCAT

Sie können sich auf das Dokument beziehen :

Wie Sie sehen, hat main nun Argumente. Der Name der Variablen argc steht für "argument count"; argc enthält die Anzahl der Argumente an das Programm übergeben. Der Name der Variablen argv steht für "Argumentvektor". Ein Vektor ist ein eindimensionales Array und argv ist ein eindimensionales Array von Strings. Jede Zeichenfolge ist eines der Argumente das wurde dem Programm übergeben.

Wenn Sie es ausdrucken möchten, entfernen Sie einfach das * und versuchen Sie Folgendes:

#include<stdio.h>
int main(int argc, char *argv[])
{
    int i;
    printf("%d\n",argc);
    for(i=0;i<argc-1;i++)
    {
        printf("%s",argv[i]);   //remove * from here
    }
    return 0;
}
0
Rahul Tripathi