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

 

 


Tema destacado: Introducción a Git (Primera Parte)


  Mostrar Mensajes
Páginas: 1 ... 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 [24] 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 ... 125
231  Programación / Programación C/C++ / Re: Programa se cierra al llamar a una funcion dentro de un do-while (lenguaje C) en: 15 Septiembre 2014, 11:10 am
Deberías aprender a leer los errores que te da el compilador. Tu código tiene un montón de errores:

Código
  1. int nombre[30];
  2. int descripcion[30];

tanto nombre como descripción han sido definidos como un array de enteros... si intentas tratar esto como una lista de strings lo vas a pasar mal.

Código
  1. char nombre[30][50];
  2. char descripcion[30][50];

Ahora, tanto 'nombre' como 'descripcion' permiten almacenar 30 strings diferentes, cada uno con una longitud máxima de 49 caracteres.



Código
  1. float ventas(int Nombre[30],int Descripcion[30],int Cantidad[30],float Precio[30],int X,int C);
  2. float impresion(int Name[30],int Descr[30],int Cant[30],float Price[30],int X1,int C1,float Precioto[30],float subto,float tax,float Total,float Altotal);

Vamos a ver, 'nombre', 'descripcion', 'cantidad' y 'precio' van siempre juntos... ¿por qué no los agrupas en una estructura? El código va a quedar mucho más bonito y legible... además, no es prudente usar funciones con muchos parámetros, por lo que interesa reducirlos al máximo:

Código
  1. // Definición de la estructura
  2. typedef struct
  3. {
  4.  char nombre[ 50 ];
  5.  char descripcion[ 50 ];
  6.  int cantidad;
  7.  float precio;
  8. } Articulo;
  9.  
  10. // ...
  11.  
  12. // Declaramos un array de 30 artículos
  13. Articulo articulos[ 30 ];
  14.  
  15. // Acceso a datos del articulo 10
  16. articulos[ 9 ].cantidad = 10;

Con esto, las funciones ahora quedan un poco más legibles:

Código
  1. float ventas( Articulo *articulos, int X, int C );
  2. float impresion( Articulo *articulos, int X1, int C1, float Precioto[30], float subto, float tax, float Total, float Altotal );

Esto aún puede mejorar un poco más, dado que tanto "ventas" como "impresion" van a recorrer toda la lista de artículos, no hace falta pasar 'X':

Código
  1. float ventas( Articulo *articulos, int C );
  2. float impresion( Articulo *articulos, int C1, float Precioto[30], float subto, float tax, float Total, float Altotal );

Y aún se le puede dar una vuelta de rosca más. Dado que el arreglo de artículos debe ir siempre acompañado del total de artículos, parece lógico agrupar estos dos elementos en una nueva estructura:

Código
  1. typedef struct
  2. {
  3.  Articulo lista[ 30 ];
  4.  int totalArticulos;
  5. } Venta;

Con lo que ahora las funciones quedan más limpias todavía:

Código
  1. float ventas( Venta *venta );
  2. float impresion( Venta *venta, float Precioto[30], float subto, float tax, float Total, float Altotal );

Mejor así, no?



Código
  1. int x=0,c=0;

¿Qué significa 'x'? ¿y 'c'? no son nombres 'válidos' porque no aportan información acerca de su finalidad. Es complicado seguir un código con variables sin sentido aparente. Hay que facilitar la lectura del código al máximo.

Por ejemplo, 'x' podría llamarse 'idArticulo' y 'c' lo podrías renombrar por 'totalArticulos'.



Código
  1. int lectura();
  2. float ventas( ... );
  3. float impresion( ... );

Si las funciones no tienen 'return algo', entonces deberían estar declaradas como 'void funcion':

Código
  1. void lectura();
  2. void ventas( ... );
  3. void impresion( ... );

Además, en C, si una función no está prensada para que reciba argumentos, hay que indicarlo poniendo 'void' entre los paréntesis:

Código
  1. void lectura( void );
  2. void ventas( ... );
  3. void impresion( ... );



Código
  1. printf("\nIngrese el nombre del cliente: ");
  2. scanf("%s",&nombre[c]);

En C, los strings son punteros, por lo que sobra ese '&' que tienes ahí

Código
  1. printf("\nIngrese el nombre del cliente: ");
  2. scanf("%s",nombre[c]);



Código
  1. do
  2. {
  3.  printf("\nIngrese el nombre del cliente: ");
  4.  scanf("%s",&nombre[c]);
  5.  
  6.  do
  7.  {
  8.    printf("\nIngrese descripcion del producto: ");
  9.    scanf("%s",&descripcion[x]);
  10.    printf("\nIngrese cantidad del producto: ");
  11.    scanf("%d",&cantidad[x]);
  12.    printf("\nIngrese precio individual: ");
  13.    scanf("%f",&precio[x]);
  14.    x++;
  15.    printf("\nIngresar otro producto? S/N ");
  16.    limprod=getch();
  17.  } while(limprod=='s'||limprod=='S');
  18.  
  19.  ventas(nombre,descripcion,cantidad,precio,x,c);
  20.  printf("\nProcesar otro cliente? S/N");
  21.  lim=getch();
  22.  c++;
  23. } while(lim=='s'||lim=='S');

Según este código... cada venta se asocia a un cliente... además este cliente puede adquirir un número indeterminado de artículos... este diseño no te va a permitir nunca guardar un historial de pedidos. Aprovechando la infraestructura que te he comentado, se podría modificar para adaptarla a estos requisitos:

Código
  1. #define MAX_LENGTH 50
  2. #define MAX_ARTICULOS 30
  3.  
  4. typedef struct
  5. {
  6.  char nombre[ MAX_LENGTH ];
  7.  char descripcion[ MAX_LENGTH ];
  8.  int cantidad;
  9.  float precio;
  10. } Articulo;
  11.  
  12. typedef struct
  13. {
  14.  char cliente[ MAX_LENGTH ];
  15.  Articulo articulos[ MAX_ARTICULOS ];
  16.  int numeroArticulos;
  17. } Venta;

He aprovechado también a introducir dos 'defines' porque no me gustan los literales metidos a pelo en el código.

Con este diseño conseguimos que cada cliente tenga su propia lista de artículos, aunque no le saques partido a dicho detalle en esta aplicación.



Código
  1. float ventas(int Nombre[30],int Descripcion[30],int Cantidad[30],float Precio[30],int X,int C)
  2. {
  3.    float precioto[30];
  4.    int n=0;
  5.    float subtotal=0,impuesto=0,total=0,altotal=0;
  6.    int cltotal=0;
  7.    for(n=0;n<X;n++)
  8.    {
  9.     precioto[n]=Cantidad[n]*Precio[n];
  10.     subtotal+=precioto[n];
  11.    }
  12.    impuesto=subtotal*0.07;
  13.    total=subtotal+impuesto;
  14.    altotal+=total;
  15.    impresion(Nombre,Descripcion,Cantidad,Precio,X,C,precioto,subtotal,impuesto,total,altotal);
  16. }

¿Es necesario hacer estos cálculos aquí?

Asumiendo que sí, no es un buen sistema porque la llamada a "impresion" tiene demasiados argumentos... imagínate el lío si intercambias por error dos argumentos. Entre otras cosas puede que no seas capaz de ver el error tras muchas horas de sufrimiento.

Apoyándonos nuevamente en el diseño que hemos ido realizando, esto se puede mejorar sustancialmente:

Código
  1. typedef struct
  2. {
  3.  char nombre[ MAX_LENGTH ];
  4.  char descripcion[ MAX_LENGTH ];
  5.  int cantidad;
  6.  float precio;
  7.  float total;
  8. } Articulo;
  9.  
  10. typedef struct
  11. {
  12.  char cliente[ MAX_LENGTH ];
  13.  Articulo articulos[ MAX_ARTICULOS ];
  14.  int numeroArticulos;
  15.  float subtotal;
  16.  float impuestos;
  17.  float total;
  18. } Venta;

Hemos añadido nuevos campos a las estructuras... ahora ya podemos actualizar el código de la función:

Código
  1. void ventas( Venta* venta, float* totalAlmacen )
  2. {
  3.  venta->subtotal = 0;
  4.  venta->impuestos = 0;
  5.  
  6.  int i;
  7.  for( i = 0; i < venta->numeroArticulos; i++ )
  8.  {
  9.    Articulo* articulo = &venta->articulos[ i ];
  10.    articulo->total = articulo->cantidad * articulo->precio;
  11.  
  12.    float impuestos = articulo->total * 0.07;
  13.    venta->subtotal += articulo->total;
  14.    venta->impuestos += impuestos;
  15.  }
  16.  
  17.  venta->total = venta->subtotal + venta->impuestos;
  18.  *totalAlmacen += venta->total;
  19.  
  20.  impresion( venta, totalAlmacen );
  21. }

Fíjate lo sencilla que ha quedado ahora la llamada a "impresion".

Si miras el código, verás que en el bucle uso el puntero "Articulo* articulo = &venta->articulos[ i ]". El puntero lo uso únicamente para reducir la cantidad de código a escribir... si no usase este puntero el código quedaría tal que:

Código
  1. for( i = 0; i < venta->numeroArticulos; i++ )
  2. {
  3.    Articulo* articulo = &venta->articulos[ i ];
  4.    venta->articulos[ i ].total = venta->articulos[ i ].cantidad * venta->articulos[ i ].precio;
  5.  
  6.    float impuestos = venta->articulos[ i ].total * 0.07;
  7.    venta->articulos[ i ].subtotal += venta->articulos[ i ].total;
  8.    venta->articulos[ i ].impuestos += impuestos;
  9. }

Parece obvio que el primer código es más legible.



El flujo de tu programa es deficiente.

"lectura" llama a "ventas" y este a su vez a "impresion". Esta cadena de llamadas debería estar controlada desde el "main". Los motivos son varios, pero tampoco es plan de escribir una tesis con este programa. Es importante intentar reducir la dependencia entre funciones.



El código final con los cambios aplicados:

Código
  1. #include <stdio.h>
  2. #include <ctype.h>
  3.  
  4. #define MAX_LENGTH 50
  5. #define MAX_ARTICULOS 30
  6.  
  7. typedef struct
  8. {
  9.  char nombre[ MAX_LENGTH ];
  10.  char descripcion[ MAX_LENGTH ];
  11.  int cantidad;
  12.  float precio;
  13.  float total;
  14. } Articulo;
  15.  
  16. typedef struct
  17. {
  18.  char cliente[ MAX_LENGTH ];
  19.  Articulo articulos[ MAX_ARTICULOS ];
  20.  int numeroArticulos;
  21.  float subtotal;
  22.  float impuestos;
  23.  float total;
  24. } Venta;
  25.  
  26. void lectura( Venta* venta );
  27. void ventas( Venta* venta, float* totalAlmacen );
  28. void impresion( Venta* venta, float totalAlmacen );
  29.  
  30. int main()
  31. {
  32.  int x;
  33.  for( x = 0; x < 50; x++ )
  34.    printf("\n");
  35.  
  36.  float totalAlmacen = 0;
  37.  Venta venta;
  38.  
  39.  lectura( &venta );
  40.  ventas( &venta, &totalAlmacen );
  41.  impresion( &venta, totalAlmacen );
  42.  return 0;
  43. }
  44.  
  45. void lectura( Venta* venta )
  46. {
  47.  int i = 0;
  48.  
  49.  printf("\nIngrese el nombre del cliente: ");
  50.  scanf("%s", venta->cliente );
  51.  
  52.  char respuesta;
  53.  do
  54.  {
  55.    printf("\nIngrese descripcion del producto: ");
  56.    scanf("%s", venta->articulos[ i ].descripcion );
  57.  
  58.    printf("\nIngrese cantidad del producto: ");
  59.    scanf("%d", &venta->articulos[ i ].cantidad );
  60.  
  61.    printf("\nIngrese precio individual: ");
  62.    scanf("%f", &venta->articulos[ i ].precio );
  63.  
  64.    i++;
  65.  
  66.    printf("\nIngresar otro producto? S/N ");
  67.    scanf( " %c", &respuesta );
  68.  
  69.  } while( tolower( respuesta ) == 's' );
  70.  
  71.  venta->numeroArticulos = i;
  72. }
  73.  
  74. void ventas( Venta* venta, float* totalAlmacen )
  75. {
  76.  venta->subtotal = 0;
  77.  venta->impuestos = 0;
  78.  
  79.  int i;
  80.  for( i = 0; i < venta->numeroArticulos; i++ )
  81.  {
  82.    Articulo* articulo = &venta->articulos[ i ];
  83.    articulo->total = articulo->cantidad * articulo->precio;
  84.    float impuestos = articulo->total * 0.07;
  85.    venta->subtotal += articulo->total;
  86.    venta->impuestos += impuestos;
  87.  }
  88.  
  89.  venta->total = venta->subtotal + venta->impuestos;
  90.  *totalAlmacen += venta->total;
  91. }
  92.  
  93. void impresion( Venta* venta, float totalAlmacen )
  94. {
  95.  printf("\n");
  96.  printf(" Nombre del cliente: x %s x", venta->cliente );
  97.  printf("\n%-30s | %-10s | %-10s | %-10s",
  98.         "DESCRIPCION",
  99.         "CANTIDAD",
  100.         "PRECIO",
  101.         "TOTAL" );
  102.  
  103.  int i;
  104.  for( i = 0; i < venta->numeroArticulos; i++ )
  105.  {
  106.    Articulo* articulo = &venta->articulos[ i ];
  107.    printf("\n%-30s | %10d | %10.2f | %10.2f",
  108.           articulo->descripcion,
  109.           articulo->cantidad,
  110.           articulo->precio,
  111.           articulo->total );
  112.  }
  113.  
  114.  printf("\n\t\t%20s %6.2f", "SUBTOTAL:", venta->subtotal );
  115.  printf("\n\t\t%20s %6.2f", "ITBMS:", venta->impuestos );
  116.  printf("\n\t\t%20s %6.2f", "TOTAL A PAGAR:", venta->total );
  117.  printf("\n");
  118.  printf("\nTotal Vendido por el Almacen: %.2f", totalAlmacen );
  119. }


232  Programación / Programación C/C++ / Re: Cadenas a variables!! urgentee:( en: 15 Septiembre 2014, 09:00 am
Usas C++, por lo que no veo un motivo claro que no te impida usar la clase string.

Además, 'cin', dispone de un método llamado 'getline'. Este método tiene el inconveniente de que requiere cadenas al estilo 'C', sin embargo, la stl dispone también de un método 'getline' y en esta ocasión si permite trabajar con strings.

Además, en C++ no hace falta usar 'typedef' para las estructuras... es redundante y queda feo.

Con estas dos características en mente, la cosa se simplifica bastante:

Código
  1. #include <iostream>
  2. #include <string>
  3.  
  4. struct Persona
  5. {
  6.  std::string nombre;
  7.  unsigned edad;
  8.  char sexo;
  9. };
  10.  
  11. int main( )
  12. {
  13.  std::string cad;
  14.  std::cout<< "introducir en una linea nombre edad sexo: ";
  15.  std::getline( std::cin, cad );
  16.  
  17.  Persona persona;
  18.  int index = cad.find_first_of( ' ', 0 );
  19.  persona.nombre = cad.substr( 0, index );
  20.  
  21.  int last = index + 1;
  22.  index = cad.find_first_of( ' ', last );
  23.  persona.edad = std::stoi( cad.substr( last, index - last ) );
  24.  
  25.  last = index + 1;
  26.  persona.sexo = cad.at( last );
  27. }

PD.: el código asume que estás metiendo los datos correctamente.
233  Programación / Programación C/C++ / Re: Ayuda con C++ y ordenar vector de strings en: 15 Septiembre 2014, 08:35 am
El código, si lo decoras con las etiquetas GeSHi, mejor. Además es un requisito en el foro :)

Si quieres currarte todo el código deberías montar un par de bucles para comparar las cadenas de dos en dos usando, por ejemplo, el algoritmo de burbuja. Para comparar las cadenas puedes usar la función strcmp. Si las cadenas no están en orden, simplemente las intercambias. Para eso puedes usar un string temporal y la función strcpy. Este código no te lo pongo porque no se hacen tareas. Puedes intentar hacerlo tu mismo y volver cuando tengas dudas sobre TU código.

Otra de las muchas formas de hacerlo, esta vez usando la clase string y las bondades de la stl:

Código
  1. std::vector< std::string > orderVecStrings(
  2.          std::vector< std::string > vecStr, int /*largoVecStr*/ )
  3. {
  4.  std::sort( vecStr.begin( ), vecStr.end( ), std::less< std::string >( ) );
  5.  return vecStr;
  6. }

También se pueden ordenar usando el contenedor 'set':

Código
  1. std::vector< std::string > orderVecStrings(
  2.          std::vector< std::string > vecStr, int /*largoVecStr*/ )
  3. {
  4.  std::set< std::string > temp{ vecStr.begin( ), vecStr.end( ) };
  5.  return std::vector< std::string >{ temp.begin( ), temp.end( ) };
  6. }

En cualquiera de los dos casos, ves que ya no se hace necesario el uso del segundo argumento de la función.
234  Programación / Programación C/C++ / Re: Bloques de memoria en C++ [Duda de Concepto] en: 11 Septiembre 2014, 11:24 am
Si tenemos 'char** bloque', entonces:

  • 'bloque' es un puntero doble a char
  • '*bloque' es un puntero a char
  • '**bloque' es un char

Se ve entonces claramente que '*bloque' no es lo mismo que '**bloque'

Ejemplo 1:

Código
  1. void funcionInutil( char bloque )
  2. {
  3.  bloque = 'a';
  4. }
  5.  
  6. void funcionUtil( char* bloque )
  7. {
  8.  *bloque = 'a';
  9. }
  10.  
  11. int main( )
  12. {
  13.  char bloque = '0';
  14.  
  15.  funcionInutil( bloque );
  16.  printf( "%c", bloque );
  17.  
  18.  funcionUtil( &bloque );
  19.  printf( "%c", bloque );
  20. }

Ejemplo 2:

Código
  1. void funcionInutil( char *bloque )
  2. {
  3.  bloque = malloc( 20, 1 );
  4.  
  5.  // Imprime la dirección de memoria que acaba de reservar
  6.  printf( "%d\n", bloque );
  7. }
  8.  
  9. void funcionUtil( char **bloque )
  10. {
  11.  *bloque = malloc( 20, 1 );
  12.  
  13.  // Imprime la dirección de memoria que acaba de reservar
  14.  printf( "%d\n", *bloque );
  15. }
  16.  
  17. int main( )
  18. {
  19.  char *bloque = NULL;
  20.  
  21.  funcionInutil( bloque );
  22.  
  23.  // Imprimirá 0, 'bloque' se ha pasado por copia, luego su valor no se puede modificar
  24.  printf( "%d\n", bloque );
  25.  
  26.  funcionUtil( &bloque );
  27.  
  28.  // Ahora si se ha podido modificar 'bloque' porque se ha pasado por referencia.
  29.  printf( "%d\n", bloque );
  30. }

Espero que con estos ejemplos quede un poco más claro el tema de los punteros, las referencias y las desreferencias.
235  Programación / Programación C/C++ / Re: cifrar un entero de 4 cifras en lenguaje C. en: 10 Septiembre 2014, 21:07 pm
En este caso el principal uso es para evitar tener que declarar otra variable temporal, ¿estoy en lo cierto ?.-

El evitar declarar una variable es un efecto colateral... simplemente es una muestra de que no hay una forma fija y concreta de hacer las cosas en programación.
236  Programación / Programación C/C++ / Re: [APORTE] C++ y bases de datos en: 10 Septiembre 2014, 17:16 pm
Bueno, largo o corto la idea es que sea útil, ya me contaréis.

Un saludo a ambos.
237  Programación / Programación C/C++ / Re: Comando personalizado que limpie pantalla en: 10 Septiembre 2014, 17:13 pm
Pues si no me equivoco, el código que has aportado hace lo que he dicho, ejecuta el comando del SO y no hace nada más.

Un saludo

doy fe de ello:

Código
  1. if(strcmp(cadena,limpiar) == 0 || strcmp(cadena,limpiarLinux) == 0 || strcmp(cadena,limpiarWind) == 0){
  2.  system("cls");
  3.  // ...
  4. }else if(strcmp(cadena,ayuda) == 0){
  5.  system("cls");
  6.  // ...
  7. }else if(strcmp(cadena,dirwindow) == 0 || strcmp(cadena,lslinux) == 0 || strcmp(cadena,dirdominica)){
  8.  // ...
  9.  system("dir");
  10. }else{
  11.  printf("\t!!! ERROR Comando no Validos.. Entrasr a (help) para ayuda\n");
  12. }
238  Programación / Programación C/C++ / Re: cifrar un entero de 4 cifras en lenguaje C. en: 10 Septiembre 2014, 13:20 pm
la idea de esas líneas es intercambiar el valor de las dos variables:

te lo pongo con valores binarios:

Código
  1. int a = 20; // 10100
  2. int b = 29; // 11101
  3.  
  4. a ^= b; // a = 01001 b = 11101
  5. b ^= a; // a = 01001 b = 10100
  6. a ^= b; // a = 11101 b = 10100
  7.  
  8. // Despues del codigo:
  9. // a = 29 -> 11101
  10. // b = 20 -> 10100

Esto es equivalente a:

Código
  1. int a = 20;
  2. int b = 29;
  3.  
  4. int temp = a;
  5. a = b;
  6. b = temp;
  7.  
  8. // Despues del codigo:
  9. // a = 29
  10. // b = 20

Esto también se puede hacer con sumas y restas:

Código
  1. int a = 20;
  2. int b = 29;
  3.  
  4. a += b; // a = 49 b = 29
  5. b = a - b; // a = 49 b = 49-29=20
  6. a = a - b; // a = 49-20=29 b = 20
  7.  
  8. // Despues del codigo:
  9. // a = 29
  10. // b = 20

Hay más formas de hacerlo, pero creo que la idea queda clara.
239  Programación / Programación C/C++ / Re: programa de alertas en: 10 Septiembre 2014, 08:20 am
Paso 1: Consigue un buen manual de C.
Paso 2: Lee dicho manual y realiza todos sus ejercicios.
Paso 3: Realiza pequeños programas por tu cuenta para terminar de asentar conocimientos.
Paso 4: Realiza este proyecto, ya no te dará problemas su desarrollo.

A groso modo ese podría ser un buen comienzo para hacer lo que quieres, pero me da que no lo vas a seguir.

En cualquier caso, si tus conocimientos en C son escasos es mejor que te pongas las pilas en C antes de meterte con este programa que, ciertamente, no es el más adecuado para aprender a programar.
240  Programación / Programación C/C++ / Re: cifrar un entero de 4 cifras en lenguaje C. en: 10 Septiembre 2014, 08:16 am
Eferion gracias por responder, tú código compila sin errores pero siempre me da como resultado cero.-

El código lo he probado y funciona perfectamente salvo por un detalle... falta un ';' en la línea 14... dudo que compile sin eso. (he usado un compilador C++)
Páginas: 1 ... 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 [24] 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 ... 125
WAP2 - Aviso Legal - Powered by SMF 1.1.21 | SMF © 2006-2008, Simple Machines