¿Las cadenas en argv son modificables?
Acabo de escribir un pequeño programa que lee 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 literales de cadena ya que puede causar un comportamiento indefinido, así que me preguntaba si las cadenas en el *argv[]
son literales que no debes cambiar.
int main(int argc, char *argv[])
3 answers
Del borrador estándar C11 N1570, §5.1.2.2.1 / 2:
Los parámetros
argc
yargv
y las cadenas de caracteres apuntada por elargv
array será modificable por el programa, y conservará su último valores entre el inicio y la terminación del programa.
Son modificables. Eso significa que no son literales de cadena.
Pero tenga cuidado : la cita superior solo se refiere a punteros a cadenas , excluyendo la obligatoria puntero nulo en argv[argc]
1.
Del borrador estándar C11 N1570, §5.1.2.2.1/2 (igual que el anterior)1:
argv[argc]
será un puntero nulo
Notas:
-
Algo con respecto a esta oración:
Sé que no debes modificar literales de cadena, ya que puede causar comportamiento indefinido [...]
"puede"? Siempre lo hace. El comportamiento indefinido incluye esperado, como si estuviera bien definido e inesperado comportamiento.
1 Gracias a @negro!
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2016-01-31 09:55:08
int main(int argc, char *argv[])
argv
es una matriz de punteros a char
(regla derecha izquierda). Pero las matrices cuando se especifican en argumentos de función se tratan como puntero a tipo de elemento de matriz, por lo que se puede decir que es puntero a puntero a char. Así que de acuerdo con la firma de principal se puede modificar. De lo contrario tendría que ser puntero a puntero a constant char
.
También por definición que no es un literal de cadena.
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2016-01-30 16:45:59
Los arrays que soportan las cadenas en argv
son modificables.
Pero no tienes forma de saber sus tamaños.
Frunciría el ceño al ver código que (intenta) aumentar el tamaño de las cadenas.
#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
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2016-01-31 10:28:43