3 Stimmen

Wie gehe ich mit argv-Zeichenfeldzuweisungen um?

Ich habe zwei Möglichkeiten gefunden, um Befehlszeilenargumente in ein Zeichenarray zu übertragen:

int main (int argc, char **argv)
{
  const char *s1 = argv[0];
  char s2[256];
  strcpy(s2, argv[0]);

  printf("s1: %s\ns2: %s\n\n", s1, s2);
}

Kompiliert mit dem IBM xlc-Compiler auf einem AIX-System Rückgabe

[MeinPrompt]> ./a.out

s1: ./a.out

s2: ./a.out

Welche Implementierung (s1 oder s2) ist richtig? s1 ist gut, weil argv[0] beliebig lang sein kann. s2 erfordert, dass die Länge von argv[0] < 256 Zeichen ist.

Ich verstehe nicht, wie/warum s1 funktionieren sollte. I denken die rechte Seite von s1 sollte zur Kompilierzeit erforderlich sein, aber ich denken sie wird zur Laufzeit generiert.

3voto

Jordan Parmer Punkte 34210

Der Grund, warum s1 funktioniert, ist, dass der Typ von argv[0] es einen Zeiger. Sie weisen lediglich die Adresse zu (nicht den tatsächlichen Wert), was sicher ist. Sie führen keine Art von Zuweisung oder Cast durch.

Ich bevorzuge in der Regel die erste Option, da Sie nur aus den Argumentvariablen lesen sollten.

3voto

Karl Voigtland Punkte 7407

Wenn Sie die Zeichenfolge nicht ändern wollen, funktioniert s1.

Wenn Sie die Zeichenfolge ändern möchten, können Sie eine Kopie davon erstellen. Sie sollten jedoch die sichereren strnlen() und strncpy() verwenden, wenn Ihr System dies unterstützt.

1voto

Ich denke, die rechte Seite von s1 sollte zur Kompilierzeit benötigt werden, aber ich denke, sie wird zur Laufzeit generiert.

Nein, sie ist jedes Mal erforderlich, wenn die Anweisung auftaucht. Zum Beispiel:

void f() {
   int x = 1;
   ...
}

Die Ganzzahl x wird bei jedem Aufruf der Funktion auf 1 initialisiert, nicht zur Kompilierzeit.

1voto

user47559 Punkte 1211

S2 hat die angenehme Eigenschaft, anfällig für einen Pufferüberlauf zu sein.

Ich habe gesehen, wie Leute den Wert von argv[0] geändert haben. In manchen Fällen (auf manchen Betriebssystemen) führt die Änderung von argv[0] dazu, dass das Programm in ps als das angezeigt wird, was Sie geändert haben.

0voto

KPexEA Punkte 16174

Wenn Sie nur auf das Argument verweisen wollen, ohne es zu ändern, dann s1 ist richtig.

Wenn Sie das Argument in irgendeiner Weise ändern müssen, müssen Sie eine Kopie davon erstellen, wie in der s2 Beispiel, sondern in der s2 Beispiel müssen Sie explizit prüfen, ob die Länge größer ist als der Puffer, in den Sie sie kopieren. Wenn Sie zum Beispiel ein Argument wie Dateiname.jpg als Eingabe nehmen und Dateiname.gif als Ausgabe speichern, müssen Sie eine Kopie dieses Arguments erstellen, da Sie die Erweiterung von .jpg in .gif ändern werden

CodeJaeger.com

CodeJaeger ist eine Gemeinschaft für Programmierer, die täglich Hilfe erhalten..
Wir haben viele Inhalte, und Sie können auch Ihre eigenen Fragen stellen oder die Fragen anderer Leute lösen.

Powered by:

X