fortnite - read from command line c
¿Son las cadenas en argv modificables? (3)
Acabo de escribir un pequeño programa que lee los argumentos de la línea de comandos en C, nada demasiado difícil. También los estaba modificando, por ejemplo, cambiando el primer carácter del parámetro a mayúsculas.
Sé que no debes modificar los literales de cadena, ya que puede causar un comportamiento indefinido, por lo que me preguntaba si las cadenas en el *argv[]
son literales que no deberías cambiar.
int main(int argc, char *argv[])
int main(int argc, char *argv[])
argv
es una matriz de punteros a char
( derecha izquierda regla ). Pero las matrices cuando se especifican en los argumentos de la función se tratan como puntero al tipo de elemento de matriz, por lo que puede decir que es puntero a puntero a char. Así que según la firma de main se puede modificar. De lo contrario tenía que ser puntero a puntero a constant char
.
También por definition que no es una cadena literal.
Del proyecto de norma C11 N1570, §5.1.2.2.1 / 2:
Los parámetros
argc
yargv
y las cadenas apuntadas por la matrizargv
serán modificables por el programa y conservarán sus últimos valores almacenados entre el inicio del programa y la terminación del programa.
Son modificables. Eso significa que no son literales de cuerda.
Pero tenga cuidado : la cita superior solo se refiere a punteros a cadenas , excluyendo el puntero nulo obligatorio en argv[argc]
1 .
Del proyecto de norma C11 N1570, §5.1.2.2.1 / 2 (igual que arriba) 1 :
argv[argc]
será un puntero nulo
Notas:
Algo con respecto a esta frase:
Sé que no debes modificar los literales de cadena, ya que puede causar un comportamiento indefinido [...]
"puede"? Lo hace siempre. El comportamiento indefinido incluye el comportamiento esperado, como bien definido e inesperado.
1 Gracias a @black!
Las matrices que soportan las cadenas en argv
son modificables.
Pero no tienes forma de saber sus tamaños.
Frunciría el ceño al ver el código que (intenta) aumentar el tamaño de las cuerdas.
#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;
}
En mi máquina, llamar a ese programa con one two three
argumentos produce
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