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
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
13705900cookie-checkSind die Zeichenfolgen in argv änderbar?yes
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