elhacker.net cabecera Bienvenido(a), Visitante. Por favor Ingresar o Registrarse
¿Perdiste tu email de activación?.


 


Tema destacado:


  Mostrar Mensajes
Páginas: 1 2 3 [4] 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 ... 112
31  Programación / Programación C/C++ / Re: Punteros a cadenas dinamicas en: 11 Abril 2018, 09:19
El fred que hay en string_input es para su variable local str. Ahora subte fijas en esa misma función se dimensiona otra variable, ret_val, que no es liberada, sino que su dirección a la que apunta es pasada a str de main y por tanto ahora es main la encargada de liberar esa memoria.
32  Programación / Programación C/C++ / Re: Roca, papel y tijeras-Problema [C] en: 9 Abril 2018, 12:24
Es x=toupper(x), ídem con y.
33  Programación / Programación C/C++ / Re: Devolver una cadena pasada como argumento a una funcion en: 9 Abril 2018, 03:18
El segundo está mal hecho porque genera desbordamiento.
Devuelves un puntero (tipo de dato de 4 u 8 bytes, según arquitectura) sobre un char (tipo de dato de 1 byte).

Por qué funciona
Código:
printf("%s",(&p)[1]);

Esta parte depende de como el compilador sitúa las variables en la memoria.
Te recomiendo que visites esto: http://www2.elo.utfsm.cl/~lsb/elo320/clases/c3.pdf

La explicación rápida es:
C ha situado ptr y p de forma contigua. Tu has hecho que ptr apunte a la cadena "hola" y mediante la función p también apuntará a "hola" (pero esa parte está mal hecha como ya te he dicho, hay desbordamiento por la diferencia de bytes entre los tipos de datos). Cuándo le das (&p)[1] a printf en verdad le estas dando ptr.

%s necesita un puntero, p es un puntero, se lo podrías así, sin florituras. Pero le has añadido [1], supongo que lo has hecho y te ha marcado error, eso es porqué lo has dereferenciado y accedido al segundo carácter. En este momento el programa ha transformado el código ascii de 'o' y se lo ha dado a printf para que busque en esa posición de memoria (la 111 en decimal) para que busque allí una cadena pero el S.O. no le ha dejado y por eso ha fallado.
Seguramente para arreglarlo habrás dicho 'pues transformo p en un puntero dándole incluyendo el operador de dirección (el &)'. Pero no has quitado el [1] y esto a generado lo siguiente:
Con & has conseguido la dirección de p, es decir su puntero, y al usar los corchetes lo has dereferenciado. Si hubieras usado (&p)[0] habrías conseguido p que se lo habrías pasado a printf y habría mostrado la cadena por p, pero al mover el offset 1 byte con el [1] (se ha movido 1 byte porqué p es un puntero a char) has apuntado a la variable ptr, que es contigua. Como se ha dereferenciado, por lo comentado antes, printf la ha aceptado y por el hecho de que apunta a la misma cadena parece que el programa ha funcionado.

En verdad lo que has tenido es mucha suerte. Por eso, y para evitarte estos errores e ir moviéndote a ciegas por el tema de los punteros léete el PDF que te he pasado.

P.D.: Siguiendo con lo que te dije el otro día sobre lo de editar los posts: Si hay respuesta de otra persona sigue en una respuesta nueva. Solo edita el mismo post si vas a añadir algo pero nadie te ha respondido.
34  Programación / Programación C/C++ / Re: Devolver una cadena pasada como argumento a una funcion en: 9 Abril 2018, 01:43
Unos pequeños cambios.

Código
  1. #include <stdio.h>
  2.  
  3. char* imprimir_cadena(const char *cadena2);
  4.  
  5. int main(){
  6.    const char *ptr="hola";
  7.    const char *p=imprimir_cadena(ptr);
  8.    printf("%s", p); // cuando se imprimen cadenas no se usa asterisco
  9. }
  10.  
  11. char* imprimir_cadena(const char *cadena2){ // nota que el tipo de dato devuelto es char*
  12.    return cadena2; //el asterico * es opcional? No, no debe estar
  13. }
35  Programación / Programación C/C++ / Re: Punteros a cadenas dinamicas en: 8 Abril 2018, 03:21
Bien, antes de nada y siguiendo las reglas del foro, no debe hacer publicaciones seguidas. Si no ha habido respuestas posteriores y quieres actualizar tu mensaje debes ir al botón 'editar' de tu último mensaje del hilo y allí añadir las novedades.

Respondiendo a tus preguntas:
1. Sí, se puede guardar la salida de getchar. Fíjate que aquí se hace
Código:
while((c=getchar())!='\n') {

2. El título está bien

3. En el código que has apuntado es puntero doble porque guarda una lista de cadenas cuando en el último el que te he hecho solo guarda una única cadena.
36  Programación / Programación C/C++ / Re: Mostrar una cadena sin especificar su tamaño en: 8 Abril 2018, 01:55
Este último que has puesto es una máquina de escribir. Lo que consigues por teclado lo sueltas por la pantalla. No hace nada más: no se puede guardar para usarlo después, tratarlo, modificarlo, en definitiva trabajar los datos. Tal como los consigues los sueltas.
37  Programación / Programación C/C++ / Re: Mostrar una cadena sin especificar su tamaño en: 7 Abril 2018, 22:05
Sí, funciona como un malloc al pasarle null, pero si te fijas el realloc está en un bucle así que se necesita realojar el array. Por eso se pasa un null al principio, para que haga una primera adquisición tipo malloc pero a las siguientes trabaja como realloc. Por eso esa construcción.
38  Programación / Programación C/C++ / Re: Mostrar una cadena sin especificar su tamaño en: 7 Abril 2018, 21:48
A ver, lástima que no haya nada como %m en windows pero se puede simular. La idea es ir adquiriendo trozos razonables de memoria con realloc, para no ir perdiendo tiempo en adquisición de memoria y copia.
En este caso se adquieren bloques de memoria de 10 bytes cada vez. Cuando se llena se adquieren 10 más de forma automática. Para el final de la adquisición de la cadena, marcado por el carácter '\n', de añade el carácter nulo '\0' para marcar el final de la cadena si hay espacio; si no añade un byte más exproceso para alojarlo.

Al final se genera una cadena dinámica del mismo tamaño que la adquirida por teclado y se le copiará el contenido. La cadena auxiliar, la utilizada para adquirir del teclado es destruida y se devuelve la cadena ajustada. Eso sí, hay que recordar destruirla cuando ya no se necesite. Se considera que un char es un byte.

Código
  1. #include <stdio.h>
  2. #include <stdlib.h>
  3. #include <string.h>
  4.  
  5. char* string_input() {
  6.    char *ret_val; // cadena que será devuelta
  7.    char *str = NULL; // cadena auxiliar para conseguir datos del teclado
  8.    char c;
  9.    const unsigned chunk = 10; // tamaño de trozos de memoria en bytes o caracteres
  10.    int i=0; // posición del cursor en str
  11.  
  12.    while((c=getchar())!='\n') { // adquisición por teclado
  13.        if(i%chunk == 0) // si i ha alcanzado el máximo de memoria
  14.            str=realloc(str, i+chunk); // añadirle más
  15.        str[i] = c; // copiar el caracter adquirido a la cadena
  16.        ++i; // avanzar el puntero en str
  17.    }
  18.    if(i%chunk == 0) // si i ha alcanzado el máximo de memoria
  19.        str=realloc(str, i+1); // añadir un byte más a str
  20.    str[i] = '\0'; // cerrar la cadena
  21.  
  22.    ret_val = malloc(strlen(str)+1); // dimensionar la cadena de regreso con el tamaño exacto
  23.    strcpy(ret_val, str); // copiar la cadena
  24.  
  25.    free(str); // borrar la cadena auxiliar
  26.  
  27.    return ret_val; // devolver la cadena resultado
  28. }
  29.  
  30. int main(void) {
  31.    char *str;
  32.  
  33.    printf("> ");
  34.    str = string_input();
  35.  
  36.    printf("%s", str);
  37.  
  38.    free(str);
  39. }

39  Programación / Programación C/C++ / Re: Corregir este error con Win32 en: 7 Abril 2018, 19:20
La cabecera precompilada, creo, te está fastidiando. Es verdad que son más rápidas a la hora de compilar pero no son tan dinámicas. Deberás borrar el archivo precompilado para que lo haga de nuevo y acepte el define.
40  Programación / Programación C/C++ / Re: Corregir este error con Win32 en: 7 Abril 2018, 16:52
Antes de cualquier include. Esto sirve para modificar el comportamiento de las librerías y por tanto debe ir antes de que estás hagan su trabajo.
Páginas: 1 2 3 [4] 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 ... 112
Aviso Legal - Powered by SMF 1.1.21 | SMF © 2006-2008, Simple Machines