[C] ¿Por que una cadena acepta mas valores que su longitud? (solucionado)

Iniciado por xiruko, 15 Abril 2012, 00:34 AM

0 Miembros y 1 Visitante están viendo este tema.

xiruko

buenas gente, no acabo de entender por que pasa esto. tengo este codigo:

int main() {
 
 char a[5];
 
 scanf("%s",a);
 printf("Cadena:\n%s\n",a);
 
 return 0;
}


entonces cuando le paso la cadena "123456789abcdef", me la devuelve completa por pantalla, y no se por que no se corta y me da solo "12345" que serian los 5 caracteres que he definido como longitud.

he leido acerca de de cadenas estaticas y dinamicas, pero yo en este caso no estoy usando ningun puntero asi que diria que es estatica... no? estaba empezando a comprender algunas cosas y me he encontrado con este problema de la longitud de la cadena y todo lo que creia comprender se ha esfumado de golpe... xD

gracias a quien me arroje un poco de luz!

david_BS

leé acerca de VLA en la red. por ejemplo en wikipedia busca VLA.

EDIT: pongo el link porque sale otra cosa
http://en.wikipedia.org/wiki/Variable-length_array

el tema es que es una norma de c/c++ para los compiladores que acepten arrays de dimension variable, aunque no se si es standard (me parece que no). Es como que se arregla automáticamente, pero no todos los compiladores lo tienen.

codeblocks me parece que si lo tiene, pero Visual Studio no.

s00rk

Puedes intentar hacer esta prueba mira, al colocar una variable de char de 5, y luego tienes otra y sobre pasas la anterior de 5 esta como abarcaste mas de lo que tienes aun lo podra escribir, PERO esta podria abarcar espacio de otra y modificar otra variable ejemplo:

Y escribe primero algo que no abarque mas de 5, y veras que lo muestra bien, pero si escribes algo mayor como de 17 caracteres .. abarcara espacio del otro ... eso podria perjudicarte bastante es por eso que Debes saber bien la cantidad de caracteres que ocuparas ...

Código (cpp) [Seleccionar]

int main()
{
        char palabra2[3];
char palabra[5];
strcpy(palabra2, "123");
scanf("%s", palabra);
printf("\n%s", palabra);
printf("\n%s", palabra2);
        return 0;
}

david_BS

claro, los 5 que reservaste son de los cuales podés estar seguro que son tuyos, ahora más a lo largo de esos 5 es memoria la cual puede estar siendo usada para otras cosas. Aparte de los compiladores con el mecanismo de VLA, lo que corresponde es usar sólo esa memoria que reservaste osea 5.

Y tratándose de cadenas siempre reserva +1 de memoria para el cero delimitador.


xiruko

#4
vale entonces, si yo marco como longitud por ejemplo 10 caracteres, y le paso una cadena de 50 caracteres, los unicos caracteres que 100% seguro guardara bien serian los 10 primeros no? y nadie me asegura que pueda acceder a los 40 caracteres restantes durante el programa ya que quizas se han sobreescrito o algo asi.

es este el razonamiento?

y respecto a lo del VLA, en el ejemplo que dan en wikipedia:

float read_and_process(int n)
{
    float vals[n];

    for (int i = 0; i < n; i++)
        vals[i] = read_val();
    return process(vals, n);
}


definen la longitud de la cadena, aunque esta dependa de n. en el caso que os he comentado, yo le doy una longitud de 5 y en cambio me deja pasarle mas caracteres, asi que no veo que sean cosas iguales. si esto no es asi, por favor explicadme el por que ya que veo que son casos distintos.

gracias a los 2!


EDIT: edito para decir que ya encontre la respuesta. por si a alguien le interesa, no llevar un control sobre la memoria asignada a un programa puede provocar esto:
http://es.wikipedia.org/wiki/Desbordamiento_de_búfer

llevo un rato mirando y para evitar que se sobrepase la longitud de la cadena se podria hacer algo asi:

#include <stdio.h>
#include <stdlib.h>

#define MAX 8 /*longitud de la cadena*/

int main() {
 
  char *pa;
 
  pa=(char*)malloc(MAX*sizeof(char));
 
  if (pa==0) {
    printf("ERROR - No hay memoria disponible.\n");
  } else {   
    printf("Introduce una cadena de maximo %d caracteres:\n",MAX-1); /*MAX-1 para dejar el caracter de fin de cadena \0*/
    scanf("%s",pa);
   
      if ((int)*(pa+MAX-1)!=0) {
printf("ERROR - Excediste los %d caracteres permitidos.\n",MAX-1);
      } else {
printf("Cadena correcta.\n");
      }
    free(pa);
  }
  return 0;
}
 


gracias de nuevo!


xiruko

pues la verdad es que no... xD

empece antes de ayer con C asi que no tengo mucha idea... aunque gracias por la recomendacion y por la web, a favoritos que va.

fary

Cita de: burbu_1 en 15 Abril 2012, 14:23 PM
leiste algo sobre la funcion strlen:huh: :huh: :huh:

Y para qeu tendría que leer sobre esa función?  :rolleyes:


Es por lo que dice david_BS, tienes que tener cuidado porque te puede sobreescribir datos esenciales y que tu exe se rompa en ejecución.

saludos.
Un byte a la izquierda.

david_BS

si el problema es que no se sobrepase la longitud entonces usa cin.getline y pasale la cantidad de caracteres máxima.

sino usá un char* con malloc, osea memoria dinámica


sino usa codeblocks XD que te permite el mecanismo de VLA aunque parece poco profesional eso de declarar un string de 5 y que puedas poner los que quieras  :rolleyes:.