Sind die Zeichenfolgen in argv änderbar?

Lesezeit: 3 Minuten

Benutzer-Avatar
Asche.KETCHUP

Ich habe gerade ein kleines Programm geschrieben, das Befehlszeilenargumente in C liest, nichts allzu schwieriges. Ich habe sie auch modifiziert, zum Beispiel das erste Zeichen des Parameters in Großbuchstaben geändert.

Ich weiß, dass Sie Zeichenfolgenliterale nicht ändern sollten, da dies zu undefiniertem Verhalten führen kann, also habe ich mich nur gefragt, ob die Zeichenfolgen in der *argv[] sind Literale, die Sie nicht ändern sollten.

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

  • Mögliches Duplikat von Wofür sind die Argumente von main()?

    – Benutzer007

    30. Januar 2016 um 14:26 Uhr

  • Es ist kein Wort. Du kannst es ändern.

    – BLUEPIXY

    30. Januar 2016 um 14:27 Uhr


  • @ user007 Kein Duplikat. Diese Frage erwähnt nichts über Zeichenfolgenliterale.

    – Spikatrix

    30. Januar 2016 um 14:30 Uhr

  • Wenn Sie in Ihrem Programm keinen String geschrieben und ihn in Anführungszeichen gesetzt haben, ist es kein String-Literal.

    – Jonathon Reinhart

    30. Januar 2016 um 14:35 Uhr

  • @JonathonReinhart oh wow das wusste ich nicht, danke!

    – Asche.KETCHUP

    30. Januar 2016 um 14:39 Uhr

Benutzer-Avatar
Cadaniluk

Aus dem C11-Standardentwurf N1570, §5.1.2.2.1/2:

Die Parameter argc und argv und die Zeichenfolgen, auf die durch die hingewiesen wird argv
Array soll durch das Programm veränderbar sein und ihre zuletzt gespeicherten Werte zwischen Programmstart und Programmende beibehalten.

Sie sind modifizierbar. Das heißt, sie sind keine String-Literale.

Aber vorsichtig sein: das obere Zitat bezieht sich nur auf Hinweise zu Saitenohne den obligatorischen Nullzeiger at argv[argc]1.
Aus dem C11-Standardentwurf N1570, §5.1.2.2.1/2 (wie oben)1:

argv[argc] soll ein Nullzeiger sein


Anmerkungen:

  • Etwas zu diesem Satz:

    Ich weiß, dass Sie Zeichenfolgenliterale nicht ändern sollten, da dies zu undefiniertem Verhalten führen kann […]

    “kann”? Das tut es immer. Undefiniertes Verhalten umfasst erwartetes, als ob wohldefiniertes und unerwartetes Verhalten.


1 Danke an @black!

  • Vielen Dank für Ihre Antwort, ich weiß, dass es immer zu undefiniertem Verhalten führt. Ich denke, ich sollte meine Frage expliziter stellen, ich werde sie jetzt ändern.

    – Asche.KETCHUP

    30. Januar 2016 um 14:41 Uhr

  • Dass dies impliziert, dass die Zeiger selbst geändert werden können oder nicht? Dh kann man tun: argv[0] = NULL

    – 2501

    30. Januar 2016 um 17:19 Uhr


  • @Jongware Soweit ich das beurteilen kann, widerspricht das erste Zitat direkt dem: “[…] die Zeichenfolgen, auf die durch die hingewiesen wird argv Array soll durch das Programm änderbar sein […],”, also, außer wenn die Argumente sind kopiert aus dem ROM, sie können nicht im Nur-Lese-Speicher gespeichert werden. Oder beziehen sich “die Zeichenfolgen” auf die Zeiger selbst? Meiner Meinung nach nicht.

    – Cadaniluk

    30. Januar 2016 um 17:29 Uhr

  • Ich bin mir ziemlich sicher, die argv[argc] == NULL-Ding ist eine Garantie der Umgebung, kein Verbot der Änderung durch das Programm.

    – EÖF

    30. Januar 2016 um 18:21 Uhr

  • @ 2501 Ich habe diesbezüglich eine Frage gestellt, nur damit Sie es wissen.

    – Cadaniluk

    30. Januar 2016 um 19:15 Uhr

Die Arrays, die die Zeichenfolgen in unterstützen argv sind modifizierbar.
Aber Sie haben keine Möglichkeit, ihre Größe zu kennen.

Ich würde die Stirn runzeln, wenn ich Code sehe, der (versucht) die Größe der Zeichenfolgen zu erhöhen.

#include <stdio.h>
#include <string.h>
// this program may behave erraticaly
int main(int argc, char **argv) {
    for (int k = 1; k < argc; k++) {
        printf("original argv[%d] is %s\n", k, argv[k]);
    }
    printf("\n");
    for (int k = 1; k < argc; k++) {
        strcat(argv[k], " foo"); // add foo to each argv string
        printf("first modification to argv[%d] is %s\n", k, argv[k]);
    }
    printf("\n");
    for (int k = argc; k > 1; k--) {
        strcat(argv[k - 1], " bar"); // add bar to each argv string
        printf("final argv[%d] is %s\n", k - 1, argv[k - 1]);
    }
    return 0;
}

Auf meiner Maschine ruft man dieses Programm mit auf one two three Argumente produziert

original argv[1] is one
original argv[2] is two
original argv[3] is three

first modification to argv[1] is one foo
first modification to argv[2] is foo foo
first modification to argv[3] is foo foo

final argv[3] is foo foo bar
final argv[2] is foo foo foo bar bar
final argv[1] is one foo foo foo bar bar bar

  • Danke dafür! Ja, ich habe die Größe nicht wirklich vergrößert oder verkleinert, sondern nur ein Zeichen in Groß- oder Kleinbuchstaben geändert.

    – Asche.KETCHUP

    31. Januar 2016 um 13:34 Uhr


1370590cookie-checkSind die Zeichenfolgen in argv änderbar?

This website is using cookies to improve the user-friendliness. You agree by using the website further.

Privacy policy