C/Visual C - Array

 
Vista:

Array

Publicado por Franco Cedillo (36 intervenciones) el 21/07/2005 08:06:40
Hola foristas,

Estuve intentando resolver el problema 4 del tema "arrays" que se presenta en el siguiente enlace: http://c.conclase.net/curso/index.php?cap=010

Mi duda surge en el tratamiento del arreglo, pues le doy un tamaño fijo y una asignación que no cubra todo el arreglo provoca un error ya que la función llamada trabaja bajo este supuesto.
Entonces no voy a supoer que el arreglo esté lleno, sino que lo llenaré de ceros siempre que sea necesario. No entiendo cómo averiguar la cantidad de ceros necesaria ni la posición inicial adecuada. También etuve pensando en que se puede trabajar directamente con el arreglo. El problema pide que incremente en una unidad el número que contiene la cadena. si no es número (sólo dígitos como elementos) arrojará false (aún no realizo esta parte del algoritmo)

Saludos.

#include <iostream.h>
#include <stdlib.h>

bool Incrementa(char numero[10])
{
bool es_digito=true;
int i=0, dig, num=0, potencia10=100000000;
while ( (i<9) && (es_digito) )
{
dig = numero[i];
if ( (dig<48) || (dig>58) )
es_digito = false;
else
{
dig = dig - 48;
num = num + dig*potencia10;
potencia10 = potencia10/10;
i++;
};
};

num++;

potencia10 = 1;

for (i=8;i>0;i--)
{
numero[i] = ((num/potencia10)%10)+48;
potencia10 = potencia10*10;
};

return (es_digito);

};

int main()
{

int i, fin=0;
char numero[10]="000000000";
// si no tengo 9 cifras entonces el programa falla
// creo que se podría completar con ceros a la izquierda
// en caso tenga menos de 9 cifras
// pero no sé cómo contar hasta el símbolo 0
// si ya tengo ceros antes, o si la última cifra es cero
if (Incrementa(numero))
for (i=0;i<9;i++)
cout<<numero[i];
else
cout<<"Error en dato";
cout<<"\n";
system("PAUSE");
return 0;

}
Valora esta pregunta
Me gusta: Está pregunta es útil y esta claraNo me gusta: Está pregunta no esta clara o no es útil
0
Responder

RE:Array

Publicado por King (18 intervenciones) el 21/07/2005 17:47:37
Hola:

El problema que tienes es un poco mas de concepto que de sintáxis. Los arreglos en C y C++ deben de terminar con un caracter de "FIN" que casi siempre es un \0 (diagonal inversa cero)

Yo te propongo, que en lugar de utilizar un arreglo estático para tu cadena de caracteres, lo hagas dinámico y en tiempo de ejecución encuentres el tamaño exacto para que el apuntador no te marque ese error:

char* miNumero = "2930029392" // <- Cualquier longitud, cualquier cadena

int size = strlen(miNumero); // te da el tamaño de la cadena

Y asi siempre vas a saber el tamaño exacto............ otro detalle, veo que estas ocupando los valores ASCII de los caracteres..... podrías mejor convertir la cadena de caracteres en un entero, para evitarte ese rollo, pero si asi se te hace mas sencillo está bien.

Saludos

http://www.novacreations.net

PD, los nombres de los métodos deben de ir en minúscula

Valora esta respuesta
Me gusta: Está respuesta es útil y esta claraNo me gusta: Está respuesta no esta clara o no es útil
0
Comentar

RE:Array

Publicado por fernando.gomez (1604 intervenciones) el 21/07/2005 18:54:09
Hola,

char* miNumero = "2930029392" // <- Cualquier longitud, cualquier cadena

esto es incorrecto, con eso no creas una cadena, sino que asignas al puntero miNumero una dirección de memoria estática que el compilador generará para esa cadena. Pero eso no es una cadena dinámica. Lo correcto sería algo como:

char miNumero[] = "2930029392";

que creará un array con tantos elementos como caracteres haya en la cadena estática. Para usar una cadena dinámica, puedes ubicar memoria:

char* miNumero = malloc(50*sizeof(char)); // C
char* miNumero = new char[50]; // C++
//...
free(miNumero); // C
delete [] miNumero; // C++

Salutes.

Valora esta respuesta
Me gusta: Está respuesta es útil y esta claraNo me gusta: Está respuesta no esta clara o no es útil
0
Comentar

RE:Array

Publicado por Franco Cedillo (36 intervenciones) el 22/07/2005 05:12:20
Hola,

el programa lo realicé de la siguiente manera :D,

/*
Hacer un programa que contenga una función con el prototipo
bool Incrementa(char numero[10]);
La función debe incrementar el número pasado como parámetro
en una cadena de caracteres de 9 dígitos.
Si la cadena no contiene un número, debe devolver false,
en caso contrario debe devolver true,
y la cadena debe contener el número incrementado.
Si el número es "999999999", debe devolver "0".
Cadenas con números de menos de 9 dígitos pueden contener ceros iniciales o no,
por ejemplo, la función debe ser capaz de incrementar tanto
la cadena "3423", como "00002323".
La función "main" llamará a la función Incrementar con diferentes cadenas.
*/

#include <iostream.h>
#include <stdlib.h>
#include <string.h>

void ImprimeNumero(char numero[10])
{
int i;
for (i=0;i<9;i++)
cout<<numero[i];
}

int IndiceInicial(char numero[10])
{
int i=0;
while ((numero[i]==48) && (i<9))
i++;
return (i);
}

void CompletaNumero(char numero[])
{
int longitud=strlen(numero);
int inicio=IndiceInicial(numero);
int num_ceros = 9 - ( longitud - inicio );
// cout<<num_ceros<<endl;
int i,j;
if (longitud != 9)
{ for (i=longitud;i<9;i++)
for(j=i;j>=0;j--)
numero[j+1] = numero[j];
for (i=0;i<num_ceros;i++)
numero[i]=48;
}
}

bool Incrementa(char numero[])
{

int longitud=strlen(numero);
int inicio=IndiceInicial(numero);
// cout<<"Longitud: "<<longitud<<endl;
// cout<<"Inicio: "<<inicio<<endl;

CompletaNumero(numero);
cout<<"Numero Original: "<<endl;
ImprimeNumero(numero);
cout<<endl;
// longitud=strlen(numero);
// inicio=IndiceInicial(numero);
// cout<<"Longitud: "<<longitud<<endl;
// cout<<"Inicio: "<<inicio<<endl;
// ImprimeNumero(numero);

bool es_digito=true;
int i=0, dig, num=0, potencia10=100000000;
while ( (i<9) && (es_digito) )
{
dig = numero[i];
if ( (dig<48) || (dig>58) )
es_digito = false;
else
{
dig = dig - 48;
num = num + dig*potencia10;
potencia10 = potencia10/10;
i++;
};
};

num++;

potencia10 = 1;
for (i=8;i>0;i--)
{
numero[i] = ((num/potencia10)%10)+48;
potencia10 = potencia10*10;
};

if (!es_digito)
return 0;

return (es_digito);

}

int main()
{

int i;
char numero[10]="103a56";
// 012345678
// 123456789

if (Incrementa(numero))
{
cout<<"Numero: incrementado: "<<endl;
(ImprimeNumero(numero));
}
else
cout<<"Error en dato. ";

cout<<"\n";
system("PAUSE");
return 0;

}

^^
Valora esta respuesta
Me gusta: Está respuesta es útil y esta claraNo me gusta: Está respuesta no esta clara o no es útil
0
Comentar

RE:Array

Publicado por Franco Cedillo (36 intervenciones) el 22/07/2005 05:13:16
Hola,

gracias por eso de char*... recién me entero que ese es un puntero :D

Gracias.
Valora esta respuesta
Me gusta: Está respuesta es útil y esta claraNo me gusta: Está respuesta no esta clara o no es útil
0
Comentar

RE:Array

Publicado por King (18 intervenciones) el 23/07/2005 08:03:04
Hola!
/********************************************************************************************/
char* miNumero = "2930029392" // <- Cualquier longitud, cualquier cadena

esto es incorrecto, con eso no creas una cadena, sino que asignas al puntero miNumero una dirección de memoria estática que el compilador generará para esa cadena. Pero eso no es una cadena dinámica. Lo correcto sería algo como:

char miNumero[] = "2930029392";
/********************************************************************************************/

lo siento pero creo que tienes un error grave de conceptos.......... no se como podrías crear una cadena (o cualquier tipo de arreglo) dinámica con el indexador........ eso es simplemente una contradicción.

Seguramente sabrás que el char* es un operador ( el asterisco es un operador) que viene sobre cargado por default para que en el antiguo estilo C el usar cadenas de caracteres DINAMICAS no fuera tan engorroso. Obvio no sirve para enteros, objetos (evidentemente) puesto que esa sobrecarga se encuentra en el archivo stdio.h, que para nuestra suerte, ya no se usa por ser un archivo antiguo.

Solo, para que el concepto quede bien claro, la sobrecarga en las cadenas de caracteres permite esta "ambiguedad":

char** es lo mismo que char[]* y es lo mismo que char[][]

inténtalo, pasale esos parámetros al main, y verás que funciona correctamente.

Saludos

King
Valora esta respuesta
Me gusta: Está respuesta es útil y esta claraNo me gusta: Está respuesta no esta clara o no es útil
0
Comentar

RE:Cadenas

Publicado por Franco Cedillo (36 intervenciones) el 24/07/2005 00:09:07
Hola,

Me confunde un poco lo de punteros.

char cadena1[] = "Cadena 1";
char *cadena2 = "Cadena 2 mas larga";
char *pcadena;

ImprimeCadena(cadena1);
ImprimeCadenaDesdePuntero(cadena2);

cout << LongitudCadena(cadena1) << endl;

En esta parte hago una asignación de dos tipos de datos diferentes.
puntero y cadena.

pcadena = cadena1;

El compilador no me dice que haya un error en esta asignación

Luego una función que recibe un puntero como parámetro funciona correctamente en ambos casos

cout << LongitudCadena(pcadena) << endl; //puntero a cadena1[0]

cout << LongitudCadena(cadena2) << endl; //cadena

===

funciones que uso

void ImprimeCadena(char cadena[])
{
cout << cadena << endl;
}

void ImprimeCadenaDesdePuntero(char* cadena)
{
cout << cadena << endl;
}

int LongitudCadena(char* pcadena)
{
int i = 0;
while ( (pcadena[i]) != 0)
i++;
return i;
}

===

Saludos
Valora esta respuesta
Me gusta: Está respuesta es útil y esta claraNo me gusta: Está respuesta no esta clara o no es útil
0
Comentar

RE:Cadenas

Publicado por King (18 intervenciones) el 24/07/2005 19:45:26
Hola!

Pues, si esta un poco confuso. Lo que pasa es que con los char es un caso especial, pues el operador está sobrecargado.

digamos, por ejemplo que quieres un arreglo de 10 numeros enteros:

int numeros[ 10 ];

Ahi estás haciendo un arreglo de 10 elementos, de tamaño fijo. Es fijo, por que la memoria que se guarda para tus elementos es CONTIGUA, es decir, toda unida. Esto es posible por que tu le estas diciendo cuanta memoria guardar ( 10 ) y por lo tanto, el compilador sabe en tiempo de compilación cuanto apartar. Como sabemos que es contigua, entonces para avanzar a travez del arreglo lo unico que hay que hacer es movernos en una dirección. desde el punto de partida, que es numeros[ 0 ].

Ahora, si lo que quieres es un arreglo de numeros, pero por alguna razón no sabes que tamaño va a tener, lo que haces es lo siguiente:

int* numeros2;
// calcula el tamaño que vas a querer, ya sea de alguna operación o que lo dé el usuario

numeros2 = new int [ tamaño ];

Te das cuenta de la diferencia de la declaración, ahora es un int* y antes un int[]. AMBOS son apuntadores, apuntan a la primer localidad de un arreglo. Sin embargo, el int* indica que el tamaño del arreglo no se sabe en tiempo de compilacíon y por lo tanto, debe ser DINÁMICO. Al hacer un arreglo dinámico, le dices al compiador que no aparte memoria, sino que en vez de eso, solo guarde un punto de entrada, como referencia, por si se necesita accesar al arreglo.

Al momento de correr el programa y de saber ya el tamaño que quieres, pides memoria dinámicamente con :

numeros2 = new int [ tamaño ];

Ahora, como esto no se sabia al momento de compilar, la memoria que se aparta no estará contigua, sino que estará fuera de la memoria que se esperaba para el programa. Si te preguntas, fuera donde? pues eso igual se lo pregunta el programa. Para contestar esa pregunta, necesitamos una dirección de memoria que va a contener el arreglo. y adivina que? pues la dirección de memoria de entrada es precisamente el int* !!!! osea el apuntador!

Por supuesto, los apuntadores son sujetos a operaciones como la asignación:

numeros = numeros2;

Y lo que haces es asignar la dirección de memoria contenida en numeros2, a la dirección de numeros. Puede parecer confuso, pero asi es, mira este ejemplo:

// suponemos que arreglo1 es un arreglo de 10 elementos enteros:
// para desplegarlo en pantalla:

for( int i = 0; i < 10; i++)
cout << arreglo1 [ i ] << endl;

// es lo mismo que movernos haciendo uso de direcciones de memoria, en lugar de
// valores puntuales:

for(int i = 0; i < 10; i++)
{
cout << *arreglo1 << endl;
(*arreglo1)++;
}

Espero que haya servido de algo

Visita mi página!

saludos

King
http://www.novacreations.net

Valora esta respuesta
Me gusta: Está respuesta es útil y esta claraNo me gusta: Está respuesta no esta clara o no es útil
0
Comentar