Strings y funciones en ANSI C

Moderadores: Kravenbcn, largeroliker, fidelcastro, cerealkiller, pspCaracas, m0skit0, LnD, ka69, zacky06

Avatar de Usuario
pspCaracas
Moderador Global
Moderador Global
Mensajes: 3080
Registrado: 03 Sep 2009, 03:29
Ubicación: Buenos Aire - Argentina
Contactar:

Strings y funciones en ANSI C

Mensaje por pspCaracas »

Bueno estoy hecho un lío con esto. Quiero pasar el valor de un string por referencia en una función, pero la verdad creo que no atino con la forma correcta (si atino porque estoy tirando flecha como decimos aquí).

Lo que quiero es algo como esto:

Código: Seleccionar todo

#include <stdio.h>
#include <string.h>

void miFuncion(char *valor){
   valor = "Un string bonito";
}

int main(int argc, char **argv){

   char *sValor;

   miFuncion(sValor);

   printf("El valor es =%s\n",sValor);

}


La salida es: "El valor es =(null)"

Si intento hacerlo con la referencia, es decir, invocándolo de la siguiente forma: miFuncion(&sValor), la salida es la misma :roll:

¿Algún sitio donde puede leer sobre el manejo de string y funciones con ANSI C?...Gracias de antemano!!
http://farm3.static.flickr.com/2497/3983880148_f5ae0aaab2_o.png

Avatar de Usuario
m0skit0
Administrador
Administrador
Mensajes: 5585
Registrado: 03 Sep 2009, 09:35
Ubicación: 0xdeadbeef

Re: Strings y funciones en ANSI C

Mensaje por m0skit0 »

En C no se puede asignar una cadena de caracteres con el operador =, porque en C char* es un puntero, no una cadena de caracteres. Necesitas usar strcpy(), o mejor, strncpy().

Aparte de todo esto, tienes otro error. Si quieres almacenar algo en char *sValor; necesitas asignarle espacio de memoria, porque sino escribirás en cualquier lugar sin tenerlo reservado, potencialmente sobrescribiendo otra zona de memoria y con un posible error de violación de segmento. Insisto, char* no es más que un puntero (una dirección de memoria).

La memoria la puedes asignar de 2 formas:

  • Estáticamente, con lo que reservas un espacio fijo siempre, con lo que se recomienda usar el valor máximo que pienses que vaya a tener la cadena de caracteres. Por ejemplo:

    Código: Seleccionar todo

    // Reserva espacio para 255 caracteres en tiempo de compilación
    char* sValor[256];
  • Dinámicamente, con lo que en tiempo de ejecución reservas el espacio que quieras usando malloc(), por ejemplo:

    Código: Seleccionar todo

    // Calculamos el tamaño a reservar (en bytes)
    int tamanio_buffer = sizeof(char)*(strlen("Un string bonito") + 1);
    // Reservamos la memoria
    char* sValor = malloc(tamanio_buffer);
    [...]
    // Liberamos la memoria reservada
    free(sValor);

Cualquier duda, pa eso estamos.
Imagen

Avatar de Usuario
pspCaracas
Moderador Global
Moderador Global
Mensajes: 3080
Registrado: 03 Sep 2009, 03:29
Ubicación: Buenos Aire - Argentina
Contactar:

Re: Strings y funciones en ANSI C

Mensaje por pspCaracas »

Al final terminé usando strcpy...la verdad que esto de los apuntadores no lo acabo de entender. Si ya el string está creado no puedo simplemente "apuntar" hacia ese string?
http://farm3.static.flickr.com/2497/3983880148_f5ae0aaab2_o.png

Avatar de Usuario
m0skit0
Administrador
Administrador
Mensajes: 5585
Registrado: 03 Sep 2009, 09:35
Ubicación: 0xdeadbeef

Re: Strings y funciones en ANSI C

Mensaje por m0skit0 »

Supongo que habrás reservado espacio como te dije también. Usar strcpy no quita el tener que reservar el espacio.

Es normal que no entiendas los punteros, personalmente me pasaba lo mismo cuando los vi por primera vez. Si las variables son cajas, piensa en un puntero como simplemente un indicador de dónde está la caja, la localización exacta de dicha caja.

Si la cadena de caracteres ya está creada, claro que sólo puedes apuntar hacia ella. Por ejemplo:

Código: Seleccionar todo

char* sValor0 = "Esta es la primera cadena\n";
char* sValor1 = sValor0;
printf("%s%s", sValor0, sValor1);

pero ten en cuenta que ambos sValor0 y sValor1 apuntan a la misma cadena. Es decir, si modificas uno de los valores, se modifica el otro. Por ejemplo:

Código: Seleccionar todo

sValor0[3] = 'o';
printf("%s%s", sValor0, sValor1);

Eso sí, nunca te olvides de reservar el espacio necesario para tu cadena, ya sea estática o dinámicamente. Puede que creas que tu programa funciona correctamente, pero no es así. Tarde o temprano te dará problemas de violación de memoria y te romperás la cabeza para averiguar por qué. ¡Reserva tu memoria siempre!
Imagen

Avatar de Usuario
pspCaracas
Moderador Global
Moderador Global
Mensajes: 3080
Registrado: 03 Sep 2009, 03:29
Ubicación: Buenos Aire - Argentina
Contactar:

Re: Strings y funciones en ANSI C

Mensaje por pspCaracas »

La explicación me sirvió mucho. No soy muy experto con eso del malloc, pero al menos sé que debo contar los caracteres reservarlos si quiero trabajar con strings dinámicos (cosa que uno ni se preocupa en Perll, Java, Python o cualquier otro lenguaje de programación del mundo).

Gracias!!
http://farm3.static.flickr.com/2497/3983880148_f5ae0aaab2_o.png

Avatar de Usuario
m0skit0
Administrador
Administrador
Mensajes: 5585
Registrado: 03 Sep 2009, 09:35
Ubicación: 0xdeadbeef

Re: Strings y funciones en ANSI C

Mensaje por m0skit0 »

pspCaracas escribió:No soy muy experto con eso del malloc, pero al menos sé que debo contar los caracteres reservarlos

Tienes que reservar los caracteres + 1, que el terminador (carácter nulo) también cuenta.

pspCaracas escribió:(cosa que uno ni se preocupa en Perll, Java, Python o cualquier otro lenguaje de programación del mundo)

Esos lenguajes son muy posteriores a C y de más alto nivel. Ya se encargan se hacer eso internamente. Y precisamente C me gusta porque tienes que hacerlo tú todo. Así aprendes cómo funcionan las cosas y no "ya lo hacen por ti". Como he dicho a veces, C es un ensamblador de alto nivel :mrgreen:
Imagen

Avatar de Usuario
pspCaracas
Moderador Global
Moderador Global
Mensajes: 3080
Registrado: 03 Sep 2009, 03:29
Ubicación: Buenos Aire - Argentina
Contactar:

Re: Strings y funciones en ANSI C

Mensaje por pspCaracas »

Lo del +1 del caracter nulo en las cadenas de caracteres no me lo sabía. Ya estoy hecho un experto (mentira jajajaj)...ya sé que si quiero hacer algo como esto:

Código: Seleccionar todo

char variable = "Un String bonito";


Debo hacer algo como:

Código: Seleccionar todo

char *variable[17] ;
strcpy(varable,"Un String bonito");


Ahora me toca aprender a hacer librerías y a parsear archivos de texto :)
http://farm3.static.flickr.com/2497/3983880148_f5ae0aaab2_o.png

Avatar de Usuario
m0skit0
Administrador
Administrador
Mensajes: 5585
Registrado: 03 Sep 2009, 09:35
Ubicación: 0xdeadbeef

Re: Strings y funciones en ANSI C

Mensaje por m0skit0 »

pspCaracas escribió:char *variable[17] ;

Nop. char variable[17], señor experto :lol: Un array es lo mismo que un puntero en C (lo cual demuestra otra vez que C es un ensamblador de alto nivel :lol: ). Por ejemplo:

Código: Seleccionar todo

char* cadena = "Un String bonito";
int i = 0;
while(cadena[i] != 0)
{
    printf("%c\n", cadena[i]);
    i++;
}


En realidad strcpy() tampoco lo uses para cadenas estáticas que ya sabes qué valor van a tener. Para eso te basta con char* cadena = "Un String bonito". En este caso el compilador lo entiende y reserva la memoria que se necesita (bueno no exactamente, pero lo dejaremos así). Lo que no puedes es manipular dinámicamente las cadenas de caracteres con operadores (+, -, =, ==, etc...). Debido a esto posteriormente los lenguajes orientados a objetos (de los que hablabas antes) crean una clase String y asignan operadores, simplificando el asunto. Pero internamente se sigue haciendo como en C ;)
Imagen

Avatar de Usuario
pspCaracas
Moderador Global
Moderador Global
Mensajes: 3080
Registrado: 03 Sep 2009, 03:29
Ubicación: Buenos Aire - Argentina
Contactar:

Re: Strings y funciones en ANSI C

Mensaje por pspCaracas »

Claro es que justamente lo que quiero hacer requiere de strings dinámicos...para más señas estoy haciendo un wrapper con el API de Sqlite, y muchas veces necesito construir las consultas de forma dinámica (allí es donde entran los strings)!!
http://farm3.static.flickr.com/2497/3983880148_f5ae0aaab2_o.png

Avatar de Usuario
m0skit0
Administrador
Administrador
Mensajes: 5585
Registrado: 03 Sep 2009, 09:35
Ubicación: 0xdeadbeef

Re: Strings y funciones en ANSI C

Mensaje por m0skit0 »

Perfecto pues, pero aún así es char* y no char*[]. Aunque para tal aplicación yo usaría algo orientado a objetos, C++ por ejemplo.
Imagen

Responder