2011-05-10 7 views
7

novice de C++ aquí. Tengo algunas preguntas básicas. En int main(int argc, char *argv[])(C++) Preguntas muy básicas sobre la sintaxis

  1. ¿Cómo se supone que char *argv[] ser leído (o hablado a los seres humanos)?
  2. ¿Es posible borrar/borrar contenido (s) específico (s), carácter (es) en este caso, de dicha matriz? Si es así, ¿cómo?
  3. ¿Se pueden cambiar el tamaño de las matrices? Si es así, ¿cómo?
  4. ¿Cómo puedo copiar todo el contenido de argv[] en una sola variable std::string?
  5. ¿Hay otras maneras de determinar el número de palabras /parámetros en argv[] sin argc? Si es así, ¿cómo? (*)

Agradecería las explicaciones (no el código) para los números 2-5. Identificaré el código yo mismo (aprendo más rápido de esta manera).

Gracias de antemano.

(*) Sé que main(char *argv[]) es ilegal. Lo que quiero decir es si hay por lo menos una forma que no implique argc en absoluto, como en las siguientes expresiones:

for(int i = 0; i < argc; ++i) { 
    std::cout << argv[i] << std::endl; 
} 

y

int i = 0;  
while(i < argc) { 
    std::cout << argv[i] << std::endl; 
    ++i; 
} 

O

int i = 0; 
do { 
    std::cout << argv[i] << std::endl; 
    ++i; } while(i < argc); 
+0

debe ser char * argv [], no char ** argv []. Se lee como "argv es una matriz de punteros a char" –

+0

Quiere decir 'int main (int argc, char * argv [])' –

+0

Sí, lo siento. Está arreglado ahora. La pregunta n. ° 1 puede que ya no sea válida. Pero simplemente me voy de allí. – Corellis

Respuesta

0

1) que se supone que ser char **argv o char *argv[] que es a pointer to an array of characters más comúnmente conocido como an array of strings

2)CString es la biblioteca std para manipular cadenas de C (arrays de caracteres). No se puede cambiar el tamaño de una matriz sin reasignación, pero se puede cambiar el contenido de los elementos refiriéndose a ella por el índice:

for(int i = 0; i < argc; ++i) 
{ 
    //set all the strings to have a null character in the 
    //first slot so all Cstring operations on this array, 
    //will consider it a null (empty) string 
    argv[i] = 0; 
} 


3) Técnicamente no, sin embargo, se puede eliminar entonces reasignados:

int *array = new int[15]; //array of size 15 
delete[] array; 
array = new int[50]; //array of size 50 

4) Esta es una manera:

string *myString; 
if(argc > 0) 
{ 
    myString = new string(argv[0]); 
    for(int i = 1; i < argc; ++i) 
     myString->append(argv[i]); 
} 

5) Sí, según Cubbi:

POSIX especifica el puntero nulo final de para argv, véase por ejemplo "La aplicación se asegurará de que la última miembro de esta matriz es un nulo puntero ."En pubs.opengroup.org/onlinepubs/9699919799/functions/exec.html

que significa que puede hacer:

char *val = NULL; 
int i = 0; 
do 
{ 
    val = argv[i++]; //access argv[i], store it in val, then increment i 
    //do something with val 
} while(val != NULL); //loop until end of argv array 
+0

En realidad, no es solo POSIX, el estándar de C++ exige que: "El valor de argv [argc] sea 0." en 3.6.1 [basic.start.main]/2 – Cubbi

+0

Gracias. Aunque desearía que no incluyeras códigos. Has arruinado la diversión de descifrar los acertijos del nuevo idioma (nuevo para mí, por cierto). :) – Corellis

+0

@Corellis Lo siento, me gusta dar ejemplos en caso de que lo que digo no esté claro, pero prometo que no te dije todo lo que se puede hacer para responder a todas tus preguntas. Hay muchas formas de resolver diferentes problemas. – Chad

0
  1. char *argv[] se puede leer como: "una matriz de punteros a char"

    char **argv puede leerse como: "un puntero a un puntero a char"

  2. Sí, se puede modificar la matriz argv. Por ejemplo, argv[0][0] = 'H' modificará el primer carácter del primer parámetro. Si con "borrar/borrar" te refieres a eliminar un personaje de la matriz y todo cambia automáticamente: no hay forma automática de hacerlo: tendrás que copiar todos los caracteres uno por uno a la izquierda (incluido el Terminación NULL)

  3. No, las matrices no se pueden cambiar de tamaño. Tendrá que crear uno nuevo y copiar los contenidos

  4. ¿Cómo desea representar TODAS las cadenas de parámetros como 1 std :: string? Tendría más sentido copiarlo a una matriz de std :: strings

  5. No, no hay una indicación especial de la última entrada en la matriz. es necesario utilizar argc

+0

Me gusta su respuesta a la pregunta no. 2. Wish SO me permitió aceptar varias respuestas. – Corellis

2
  1. trata de una matriz de punteros a char.

  2. Más o menos - puede sobrescribirlos.

  3. Copiando solamente a una nueva matriz.

  4. Escriba un bucle y anexe cada argv [i] a una cadena de C++.

  5. La mayoría de las implementaciones terminan la matriz con un puntero NULL. No recuerdo si esto es estándar o no.

+1

cadenas terminan con un puntero NULL, pero las matrices no lo son. – Chad

+0

¡Buena velocidad de escritura! POSIX especifica el puntero nulo final para argv, consulte por ejemplo "La aplicación se asegurará de que el último miembro de esta matriz sea un puntero nulo". en http://pubs.opengroup.org/onlinepubs/9699919799/functions/exec.html – Cubbi

+0

@Chad. Lo son si alguien (en este caso los implementadores del compilador) pone un NULL en ellos. –

0
  1. Se habla como "matriz de punteros a punteros a carácter" (tenga en cuenta que esta no es la firma de la función principal, que es ya sea int argc, char **argv o int argc, char *argv[] - que es equivalente).
  2. La matriz argv es modificable (falta de const). Sin embargo, es ilegal escribir más allá del final de una de las cadenas o extender la matriz; si necesita extender una cadena, cree una copia y almacene un puntero en la matriz; si necesita extender la matriz, cree una copia de la matriz.
  3. No se pueden cambiar de tamaño per se, pero se pueden reinterpretar como una matriz más pequeña (que de alguna manera explica la respuesta a la última pregunta).
  4. Perderá información de esta manera: argv es una matriz de matrices, porque los argumentos individuales ya se han separado para usted. Puede crear una lista de cadenas usando std::list<std::string> args(&argv[1], &argv[argc]);.
  5. No realmente. La mayoría de los sistemas tienen ARGV NULL terminado, pero eso no es una garantía.
-1

matriz en C/C++ no es un objeto, sino simplemente un puntero al primer elemento de la matriz, por lo que no se puede simplemente eliminar o insertar los valores.

responder a sus preguntas:

  1. char *argv[] se puede leer como 'matriz de punteros a char '
  2. Es posible, pero implica manipulaciones directas con datos en la memoria, como copiar y/o mover bytes.
  3. No. Pero es posible asignar nueva matriz y copiar los datos NECESARIO
  4. Al copiar manualmente cada elemento en std::string objeto

A modo de resumen: C++ es mucho más lenguaje de bajo nivel que Crees.

+0

No hay lenguaje C/C++, aunque las matrices son esencialmente las mismas tanto en C como en C++. En ninguno de los dos lenguajes, una matriz es solo un puntero, aunque tienden a decaer en punteros de uso. Tanto en C99 como en C++, 'argv [argc]' garantiza que es el puntero nulo, por lo que puede usarlo para indicar el número de miembros de 'argv'. C++ tiene elementos de bajo nivel, mayormente tomados de C, pero los programas modernos de C++ tienden a no usarlos. –

1
char **argv[] 

Es incorrecto. Debe ser char **argv o char *argv[], no una mezcla de ambos. Y luego se convierte en un puntero a puntero a los caracteres, o más bien un puntero a c-strings, es decir, una matriz de c-strings. :) cdecl.org también es bastante útil en este tipo de cosas.
Luego, para el acceso, seguro. Solo, bueno, acéptalo. :) argv[0] sería la primera cadena, argv[3] sería la cuarta cadena. Pero no recomendaría reemplazar cosas en una matriz que no sea tuya o que conozcas las partes internas de.
En el cambio de tamaño de la matriz, ya que está escribiendo C++, use std::vector, que hace todo lo complicado de la asignación para usted y es realmente seguro. En general, depende del tipo de matriz. Las matrices asignadas dinámicamente (int* int_arr = new int[20]) pueden, las matrices estáticas (int int_arr[20]) no pueden.
Para copiar todo en argv en un solo std::string, recorra el conjunto y anexe cada cadena al std::string. Sin embargo, no lo recomendaría, más bien tengo un std::vector<std::string>, es decir, una matriz de std::strings, cada uno con uno de los argumentos.

std::vector<std::string> args; 
for(int i=0; i < argc; ++i){ 
    args.push_back(argv[i]); 
} 

En su último punto, ya que la norma exige argv que ser terminada por un puntero NULL, es bastante fácil.

int myargc = 0; 
char** argv_copy = argv; 
while(++argv_copy) 
    ++myargc; 

El while(++argv_copy) se primera incrementar el puntero de la matriz, dejando que apunte al siguiente elemento (por ejemplo, después de la primera iteración se señalarán en c-string # 2 (argv[1])). Después de eso, si el puntero se evalúa como falso (si es NULL), el bucle se frena y tiene su myargc. :)

+0

Gracias por su respuesta detallada. Lástima que no puedo aceptar más de una respuesta. – Corellis

1
  1. Varias opciones: array of pointer to char OR array of C-string.

  2. Puede asignar caracteres concretos para borrarlos, o puede desplazar el resto de la matriz hacia adelante para "borrar" caracteres/elementos.

  3. Las matrices de estilo C normal no se pueden cambiar de tamaño. Si necesita una matriz redimensionable en C++, debe usar std::vector.

  4. Tendrá que iterar sobre cada uno de los elementos y anexarlos a una cadena. Esto se puede lograr con algoritmos de C++ como copy junto con un ostream_iterator utilizado en un ostringstream.

  5. No. Si no era tal manera, no habría ninguna necesidad de argc. EDITAR: Aparentemente para argvsolo el elemento final de la matriz es un puntero nulo.