Menú

Mostrar Mensajes

Esta sección te permite ver todos los mensajes escritos por este usuario. Ten en cuenta que sólo puedes ver los mensajes escritos en zonas a las que tienes acceso en este momento.

Mostrar Mensajes Menú

Mensajes - eferion

#641
Programación C/C++ / Re: Alinear texto
24 Marzo 2014, 20:52 PM
Presuponiendo que el ancho va a ser fijo es más sencillo usar printf


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

int main()
{
int i, j;
int ColumnsWidth[4] = { 10, 10, 20, 10 };

/* Contenido de la tabla, pones luego el código que la genera */
char *tabla[2][4] = { {"Hacker", "Perro", "Labrador", "Macho"},
                       {"Fugi", "Camaleon", "Silvestre", "Hembra"} };

char *titulos[4] = {"Nombre", "Animal", "Raza", "Sexo"};

char config[8];
int total = 0;
for ( j = 0; j < 4; j++ )
{
   sprintf( config, "%%-%ds", ColumnsWidth[ j ] );
   printf( config, titulos[ j ] );
   total += ColumnsWidth[ j ];
}

putchar( '\n' );

while ( total )
{
   putchar( '-' );
   total--;
}

putchar( '\n' );

for ( i = 0; i < 2; i++ )
{
   for ( j = 0; j < 4; j++ )
   {
     sprintf( config, "%%-%ds", ColumnsWidth[ j ] );
     printf( config, tabla[ i ][ j ] );
   }
   printf( "\n" );
}

return 0;
}


Y bueno, ya puestos no es complicado adaptar este código a anchos variables.


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

int main()
{
int i, j;
int ColumnsWidth[4] = { 0 };

/* Contenido de la tabla, pones luego el código que la genera */
char *tabla[2][4] = { { "Hacker", "Perro", "Labrador", "Macho" },
                       { "Fugi", "Camaleon", "Silvestre", "Hembra" } };

char *titulos[4] = { "Nombre", "Animal", "Raza", "Sexo" };

for ( j = 0; j < 4; j++ )
{
   size_t width = strlen( titulos[ j ] );
   if ( width > ColumnsWidth[ j ] )
     ColumnsWidth[ j ] = width;

   for ( i = 0; i < 2; i++ )
   {
     width = strlen( tabla[ i ][ j ] );
     if ( width > ColumnsWidth[ j ] )
       ColumnsWidth[ j ] = width;
   }

   ColumnsWidth[ j ] += 2;
}

char config[8];
int total = 0;
for ( j = 0; j < 4; j++ )
{
   sprintf( config, "%%-%ds", ColumnsWidth[ j ] );
   printf( config, titulos[ j ] );
   total += ColumnsWidth[ j ];
}

putchar( '\n' );

while ( total )
{
   putchar( '-' );
   total--;
}

putchar( '\n' );

for ( i = 0; i < 2; i++ )
{
   for ( j = 0; j < 4; j++ )
   {
     sprintf( config, "%%-%ds", ColumnsWidth[ j ] );
     printf( config, tabla[ i ][ j ] );
   }
   printf( "\n" );
}

return 0;
}


He aprovechado tu código yoel_alejandro para poner mi idea... estoy un poco apurado de tiempo. Espero que no te importe.
#642
Programación C/C++ / Re: Alinear texto
24 Marzo 2014, 14:58 PM
y el código que genera esta salida es...
#643
Programación C/C++ / Re: [DUDA] Punteros
24 Marzo 2014, 13:46 PM
Efectivamente, ni soy profesor ( ni en el foro ni en "la vida real" jejeje ) ni tampoco cobro por ayudar en la medida de mis posibilidades.

Sin embargo tu puedes preguntar tus dudas que aquí te ayudaremos lo mejor que podamos.

PD.: si alguien se apiada de mí, acepto donaciones encantado XDDDD
#644
Programación C/C++ / Re: [DUDA] Punteros
24 Marzo 2014, 12:47 PM
Mira que dudo yo que el primer ejemplo te funcione...

int i=0,vocales[5];

En qué momento se supone que inicializas los valores para "vocales"??

Y bueno, pasando al segundo código, te cuento.

Imagínate que tienes un puntero, no se, algo tal que


int * pv;
pv = &vocals[0];


Si tu depuras, pv tendrá algo tal que...


pv = 0x45672240 // Posicion de memoria apuntada por pv
*pv = 234523 // Valor de vocals[ 0 ] porque no la has inicalizado


Si tu coges pv y, por ejemplo, haces:

pv++;

entonces pv queda tal que:


pv = 0x45672244 // Nueva posicion, ahora es vocals[1]
*pv = -345023 // vocals[ 1 ] tampoco esta inicializada, tiene un valor aleatorio


Es decir, con pv++, pv = pv+6 y cosas así únicamente modificas la posición de memoria a la que apunta, pero no modificas el valor de esa posición de memoria apuntada.

Sin embargo, ahora imagínate ( para simplificar el ejemplo ) que has inicializado vocals. Entonces pv queda algo así:


pv = 0x45672240 // Posicion de memoria apuntada por pv
*pv = 0// Valor de vocals[ 0 ]


y ahora haces lo siguiente:

*pv = *pv + 1

Ahora la cosa queda tal que


pv = 0x45672240 // Posicion de memoria apuntada por pv ( no ha cambiado )
*pv = 1// Valor de vocals[ 0 ]


Que es el resultado esperado si lo que quieres es contar apariciones.

Ahora bien, esto te sirve para el valor apuntado por pv... pero si ahora nos encontramos con algo tal que:


else if(frase[i]=='e' || frase[i]=='E')
{
  pv=pv+1; // Esta linea no la he cambiado
  *pv = *pv + 1;
}


Entonces, efectivamente, haces que pv apunte a vocals[1] e incrementas el contador de la 'e'... pero después, pv se queda apuntando al contador de 'e'... imagínate que te encuentras con una frase tal que 'ee'... al ejecutar el código verás que te va a contar una e y una i... ¿por que? pues porque NO DEBES hacer pv = pv + 1. O al menos, si lo haces, restaura pv a su posición original...

Una recreación del fallo:

* Situacion original:


pv = 0x45672240
*pv = 0


Primera 'e':


pv = 0x45672244 // pv = pv + 1
*pv = 1 // *pv++


Segunda 'e'


pv = 0x45672248 // pv = pv + 1 MAL, deberia ser 0x45672244, este es el contador de 'ies'
*pv = 1


No se si ha quedado claro lo que pretendo transmitir.
#645
Programación C/C++ / Re: Problemas con c++.
24 Marzo 2014, 12:32 PM
Cita de: #Aitor en 24 Marzo 2014, 12:16 PM
¿A qué os referís cuando decís cast?

Cast es una operación de conversión:

Código (cpp) [Seleccionar]

int numero = -5;

cout << numero << endl << (unsigned int ) numero << endl;


Las conversiones, en C++, se pueden hacer de dos formas:

* Usando la sintaxis de C (opción no recomendable ), esto es, poniendo entre paréntesis el tipo al que se quiere convertir el dato ( como el ejemplo anterior ).

* Usando la sintaxis de C++. C++ dispone de herramientas para hacer conversiones ( static_cast, dynamic_cast, reinterpret_cast, const_cast ). Cada una tiene un uso determinado, aunque las más comunes son static_cast y dynamic_cast.

Algunas de las ventaja de este tipo de conversiones frente a las clásicas de C:

* Es más fácil localizar las conversiones buscando en el código. No es lo mismo buscar static_cast que "( int )" + "(int)" + "( int)" + "(int )" + ...

* Ofrecen más seguridad en la conversión. Si la conversión no es segura o no se puede realizar aparecerá un error en compilación... sin embargo los conversores de C no dan nunca error.
#646
fopen, fwrite, fread son funciones de C.

Puedes identificar de forma más o menos sencilla C de C++ por la sintaxis.

Los objetos de C++ tienen una forma tal que:

Código (cpp) [Seleccionar]

ofstream stream( "ruta", ios_base::out );
stream << buffer;
stream.close( );


Mientras que el código C se parece más a


FILE *fichero = fopen( "ruta", "w+" );
fwrite( fichero, sizeof( algo ), 20, buffer );
fclose( fichero );


En C++ se llaman a miembros de las clases mientras que en C se llama a funciones.
#647
Programación C/C++ / Re: Problemas con c++.
24 Marzo 2014, 11:48 AM
Código (cpp) [Seleccionar]
string cadena;

"cadena", tal y como la has declarado, es de tipo "string".

En C++, "string" es una clase y como tal tiene una serie de funciones y métodos a modo de interfaz que te permiten utilizarla.

Para el caso que comentas debes saber que las clases de C++ no las puedes usar como si fuese C. Son cosas diferentes.

Si miras la documentación de la clase string, verás que tiene un método "size( )", como te comento amchacon. Este método te devuelve la longitud de la cadena almacenada en el objeto correspondiente.

Código (cpp) [Seleccionar]

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

using namespace std;

int main()
{
 string cadena;
 cin >> cadena;

 int f = cadena.size( );

 while ( f >= 0)
 {
   cout << char( cadena[ f-1 ] );
   f--;
 }
}


Ahora el código compila, que no es poco. Sin embargo, tu bucle tiene demasiado código para lo que hace:

* Si usas C++ no pongas includes de C ( los que acaban en .h )
* No hace falta hacer un cast a char, ya que la clase std::string gestiona un array de char internamente.
* f-1 y f-- viene a ser más o menos lo mismo... estás haciendo dos veces lo mismo.
* while ( f>=0 )... si estás decrementando dentro del bucle tienes un problema... si f == 0, entonces cout << char( cadena[ 0-1 ] ); ... te puedes hacer a la idea.

Código (cpp) [Seleccionar]

#include <iostream>
#include <string>

using namespace std;

int main()
{
 string cadena;
 cin >> cadena;

 int f = cadena.size( ) - 1;

 while ( f >= 0)
 {
   cout << cadena[ f ];
   f--;
 }
}


Por cierto, aunque no venga a cuento del hilo:

Código (php) [Seleccionar]

while($Se_feliz){
  Piensa_un_OBJETIVO(); // Sin excusas!
  if($Tienes_un_objetivo){
    Suspira(); // Sé paciente.
    if($Consigues_el_objetivo){ echo "¡Felicidades #Aitor!";return;
      //RETURN; ¿O volvemos a empezar?
    }else{
      Inténtalo_de_nuevo();
    }
  }
}


Así queda más claro ;)
#648
Programación C/C++ / Re: Estructuras en C
22 Marzo 2014, 13:34 PM
No entiendo el motivo por el que quieres depurar por línea de comandos...

La interfaz gráfica de los IDEs te proporciona esa misma información:

* variables disponibles
* valor de las variables
* modificar el valor de las variables
* cambiar la siguiente línea de ejecución
* insertar y eliminar breakpoints

Aún así, para depurar por línea de comandos tendrás que ir a la página oficial del depurador en cuestión y buscar un tutorial que te explique su funcionamiento... eso puede variar bastante de un depurador a otro.
#649
De nada. Para lo que necesites.

Ya nos irás comentando tus progresos :)
#650
Eso sí, en programación Web te sugiero que sigas esta premisa SIEMPRE y sin excepciones... los efectos de no hacerlo pueden ser devastadores para tu portal:

Valida SIEMPRE SIEMPRE SIEMPRE toda la información que recibas ( ya vengan por GET o por POST. No asumas nunca que un dato va a ser numérico por mucho que un chiringuito montado con javascript en el lado del cliente impida introducir letras... es extremadamente sencillo saltarse este tipo de protecciones.