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

 

 


Tema destacado: Guía actualizada para evitar que un ransomware ataque tu empresa


  Mostrar Mensajes
Páginas: 1 ... 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 [21] 22 23 24 25 26
201  Programación / Programación C/C++ / Re: - Existe diferencia entre '\0' y "\0" en: 2 Marzo 2014, 20:52 pm
Así es, el carácter nulo '\0' es de tipo char, mientras que "\0" es una cadena, o sea que es tipo char*, un puntero. Por eso, estrictamente hablando, son cosas diferentes.

202  Programación / Programación C/C++ / Re: Problema con loop en: 2 Marzo 2014, 20:38 pm
Más clara imposible la explicación de por qué se llama "array de arrays" de caracteres.

De acuerdo también con el aporte de leosansan de verificar la integridad del dato suministrado por el usuario, y limpiar el búfer de entrada descartando los caracteres encontrados hasta llegar al fin de línea.

Creo que no tengo aportes que hacer a este tema ... ya se ha dicho todo, al menos al nivel que requiere quién inició la pregunta.
203  Programación / Programación C/C++ / Re: problema con la variable float en: 2 Marzo 2014, 20:27 pm
Claro, el error no tiene que ver con el float, sino con el uso de métodos de E/S de C++ (cout, endl) que requieren como ya te dijeron declarar "using namespace std"

Y concuerdo también en que debes estar atento a los mensajes del compilador, con el tiempo serás diestro en interpretarlos y saber exáctamente a qué parte del programa se refieren.
204  Programación / Programación C/C++ / Re: [C] pase de parametros en: 1 Marzo 2014, 16:17 pm
Hola, supongo que tu intención es que la función "uno" tome su parámetro y se lo pase a la función "dos". En ese caso, me voy a tomar la libertar de cambiar el nombre del miembro entero de la estructura numero de "n" a "x". Pues tienes un uso duplicado de nombres que si bien no es un error, puede resultar confuso. Así quedaría:

Código
  1. #include<stdio.h>
  2. typedef struct
  3. {
  4.  int x;
  5. }numero;
  6.  

También te aconsejaría que cuando el argumento se refiera a un puntero, uses un sufijo distintivo como "Ptr", o "_ptr". Quedaría entonces:

Código
  1. void uno (numero *n_ptr);
  2. void dos (numero *n_ptr);

Ahora vamos al centro del problema. En C todos los argumentos de las funciones se pasan por valor. Es decir, se pasa como argumento de la función una copia del valor de la variable. Pero se puede simular el paso por referencia, dando como argumento la dirección de la variable en cuestión (ésto eso, se pasa un puntero a dicha variable). Lo cual permite alterar directamente la variable al manipular en el área de memoria ocupada por ésta. Sólo ten en cuenta que en el código de la función debes usar el operador de indirección "*" para acceder al contenido de la variable, apuntado por la dirección suministrada.

Por ejemplo, supongamos que "uno" pasa el valor de su argumento (un puntero) a "dos", la cual modifica el valor del campo x de la estructura referenciada. Entonces sería

Código
  1. main()
  2. {
  3.  numero n;
  4.  uno(&n);
  5. }
  6.  
  7. void uno (numero *n_ptr)
  8. {
  9.   dos (n_ptr);    // se pasa una copia del puntero a "dos"
  10. }
  11.  
  12. void dos (numero *n_ptr)
  13. {
  14.    (*nptr).x += 1;
  15. }

Observa que en el código de "dos" se accede al contenido apuntado por n_ptr (el contenido de la variable n) por medio de (*n_ptr). Se requieren los paréntesis porque el operador "." tiene mayor prioridad que el "*", y de no colocarlos se interpretaría *(n_ptr.x) que es incorrecto pues n_ptr es un apuntador y no una estructura.

Por último, aquí puedes ver el código completo y al compilar y ejecutar verás que aunque hemos puesto inicialmente el valor de n.x en 3, al final termina siendo 4  :D

Código
  1. #include<stdio.h>
  2.  
  3. typedef struct
  4. {
  5.  int x;
  6. }numero;
  7.  
  8. void uno (numero *n_ptr);
  9. void dos (numero *n_ptr);
  10.  
  11. main()
  12. {
  13.  numero n;
  14.  n.x = 3;
  15.  printf ("antes n.x era: %d\n", n.x);
  16.  uno (&n);
  17.  printf ("ahora n.x es: %d\n", n.x);
  18. }
  19.  
  20. void uno (numero *n_ptr)
  21. {
  22.   dos (n_ptr);    // se pasa una copia del puntero a "dos"
  23. }
  24.  
  25. void dos (numero *n_ptr)
  26. {
  27.    (*n_ptr).x += 1;
  28. }
205  Programación / Programación C/C++ / Re: problema con "hola mundo" en: 1 Marzo 2014, 15:18 pm
Ah, ..... y no uses system("PAUSE"). Las órdenes system dependen su comportamiento del sistema operativo por lo que pueden hacer el programa "no portable" entre distintas máquinas. En su lugar usa getchar() que es una función estándar de C y por lo tanto tiene un comportamiento bien definido.
206  Programación / Programación C/C++ / Re: Macros en C en: 14 Febrero 2014, 21:07 pm
Así mismo es m@o_614, el preprocesador de C sustituye cada aparición del identificador o nombre de la macro por el texto de reemplazo que haya sido definido. El texto final obtenido es pasado al compilador (obviamente para que lo compile, jeje).

Una aplicación puede ser si tienes un programa donde se define un valor que aparece muchas veces en el mismo. Si quieres cambiar ese parámetro, tendrías que editar manualmente sus apariciones. Por ejemplo, quieres leer un total de digamos 3 enteros dados por el usuario y formar un vector o arreglo con ellos y luego imprimir el valor de dichos elementos:

Código
  1. #include <stdio.h>
  2. #include <stdlib.h>
  3.  
  4. int main(void)
  5. {
  6. int i, x[3];
  7.  
  8. /* pedir numeros al usario */
  9. for ( i = 0; i < 3; i++ ) {
  10. printf( "Intro valor %d: ", i+1);
  11. scanf( "%d", &x[i] );
  12. getchar();
  13. }
  14.  
  15. /* imprimiendo contenido del arreglo */
  16. for ( i = 0; i < 3; i++ ) {
  17. printf( "Valor %d: %d\n", i+1, x[i] );
  18. }
  19.  
  20. return EXIT_SUCCESS;
  21. }

Observa que el valor "3" aparece tres veces en el código. Si quisieras modificar tu programa para que reciba no 3 sino 5 valores, tendrías que editar en dos líneas diferentes de dicho código. Una alternativa sería definir una constante simbólica N, e indicar que cada aparición suya debe reemplazarse por el valor 3:

Código
  1. #include <stdio.h>
  2. #include <stdlib.h>
  3.  
  4. #define N 3
  5.  
  6. int main(void)
  7. {
  8. int i, x[N];
  9.  
  10. /* pedir numeros al usario */
  11. for ( i = 0; i < N; i++ ) {
  12. printf( "Intro valor %d: ", i+1);
  13. scanf( "%d", &x[i] );
  14. getchar();
  15. }
  16.  
  17. /* imprimiendo contenido del arreglo */
  18. for ( i = 0; i < N; i++ ) {
  19. printf( "Valor %d: %d\n", i+1, x[i] );
  20. }
  21.  
  22. return EXIT_SUCCESS;
  23. }

Si quieres que el programa reciba 5 valores sólo debes cambiar una línea y poner #define N 5

Las instrucciones #define no van terminadas en punto y coma, puesto que no son instrucciones de asignación de valor a una variable, sino un reemplazo formal de texto en el código fuente.
207  Programación / Programación C/C++ / Re: Problema Matriz cuadrada con números aleatorios sin repetir en: 14 Febrero 2014, 20:48 pm
Acabo de ver que este tema fue respondido al usuario en otro foro de C.
208  Programación / Programación C/C++ / Re: Duda con programa - funcion strlen? en: 11 Febrero 2014, 22:21 pm
Lo que plantea eferion es verdad. Una buena manera (sencilla) de limitar la longitud de la cadena de entrada es usar fgets (es lo mismo que explican en el post referenciado). Su prototipo es

Código
  1. fgets( char * buffer, int N, FILE * stream );

donde buffer es la cadena donde será copiada la entrada, N es la mayor cantidad de caracteres copiados al array incluyendo el nulo de terminación (por lo que leerá máximo N-1 caracteres), y stream es el flujo o archivo de donde leerá los datos. Debemos poner "stdin" para lea de la entrada estándar (teclado).

De este modo, reemplaza la sentencia

Código
  1. scanf("%s", nombre);

por

Código
  1. #define N 40
  2. char nombre[N];
  3.  
  4. fgets( nombre, N, stdin );

que leerá máximo 39 caracteres de la entrada estándar.
209  Programación / Programación C/C++ / Re: Buenas prácticas con C++ en: 11 Febrero 2014, 22:11 pm
Excelente eferion  ;-)

En lo particular yo soy un purista de C (y la programación de bajo nivel), pero voy a a tratar de incursionar un poco en las clases contenedoras predefinidas de C++. Si son estándares y altamente conocidas, vale la pena empezar a usarlas jeje.
210  Programación / Programación C/C++ / Re: problema con sprintf en: 11 Febrero 2014, 03:01 am
Una observación, la función fgets() es más segura por cuánto permite limitar la longitud de la cadena recibida (el argumento MAX que le pasas), y así prevenir un desbordamiento del búfer. Una verificación que no hacen ni gets() ni scanf(). De hecho, algunos compiladores advierten sobre el uso riesgoso de gets() , desaconsejando su uso.

Yo en su lugar seguiría usando fgets() pero "recortaría" la cadena:

Código
  1. if ( ( len = strlen( nombre ) ) > 0 && nombre[len - 1] = '\n') nombre[len - 1] = '\0';

Ahora, respecto a que quieres pasar el nombre del archivo sin distinguir mayúsculas y minúsculas lo veo un poco más difícil. Obviamente, no te vas a poner a probar todas las combinaciones de minúsculas y mayúsculas, a ver si alguna abre el archivo (jeje)

A mi se me ocurre listar el contenido del directorio, y probar nombre por nombre contra el nombre dado por el usuario. Si alguno coincide (despreciando mayúsculas y minúsculas), abrir el fichero. Para eso, se requiere un compilador que implemente la biblioteca <unistd.h> la cual obedece un estándar llamado POSIX. Es hecho que sea estándar significa que con seguridad la tienes en una implementación de C para Linux, pero no necesariamente en Windows  :silbar: (ya saben como es Microsoft, rompe-estándares).  

¿Usas Windows verdad? En ese caso, compila con IDE libre para Windows como Dev-Cpp, o MinGW con gcc/g++. No estoy seguro que Borland C lo soporte (la verdad no tengo idea, pues no uso ni Windows ni Borland, jeje).

Bueno, a lo nuestro.
Código
  1. #include <stdio.h>
  2. #include <stdlib.h>
  3. #include <string.h>
  4. #include <dirent.h>
  5. #include <ctype.h>
  6.  
  7. #define MAX 40
  8.  
  9. char * str_to_lower( char *);
  10.  
  11. int main()
  12. {
  13. FILE *fd = NULL;
  14. char name[MAX];
  15. unsigned long len;
  16. char ready;
  17.  
  18. char dir_name[100]; /* nombre de directorio */
  19. DIR * dir_ptr = NULL; /* apuntador a directorio */
  20. struct dirent * dirent_ptr; /* estructura 'directory-entry' */
  21. char * f_name; /* name de cada fichero leído en el directorio */
  22.  
  23. printf("Que archivo quieres abrir: ");
  24.  
  25. fgets( name, MAX, stdin );
  26. /* quitamos el '\n' al final de la cadena */
  27. if ( ( len = strlen( name ) ) > 0 && name[len - 1] == '\n' )
  28. name[len - 1] = '\0';
  29. strcat( name, ".txt" ); /* añadimos '.txt' al final */
  30.  
  31. /* pongamos el directorio como el actual, puedes cambiarlo xD */
  32. strcpy( dir_name, ".");
  33.  
  34. /* 'abrimos' el directorio para leer su contenido */
  35. if ( ( dir_ptr = opendir( dir_name ) ) == NULL ) {
  36. printf( "No existe o no se pudo abrir el directorio '%s'\n", dir_name );
  37. return -1;
  38. }
  39.  
  40. /* ahora recorremos todo el directorio, buscando
  41. * names de fichero que coincidan */
  42. ready = 0;
  43. while ( ( dirent_ptr = readdir( dir_ptr ) ) != NULL ) {
  44. f_name = dirent_ptr -> d_name;
  45.  
  46. /* verificamos omitiendo mayúsculas y minúsculas */
  47. if ( ! strcmp( str_to_lower(name), str_to_lower(f_name) ) )
  48. if((fd = fopen(f_name, "r")) != NULL) {
  49. printf("Se abrio '%s'\n", f_name);
  50. ready = 1;
  51. }
  52. }
  53.  
  54. /* y si al finalizar el ciclo no encontro, emitir error */
  55. if ( !ready )
  56. printf("No se pudo abrir el archivo\n");
  57.  
  58. /* cerramos el directorio, y el fichero */
  59. if ( dir_ptr != NULL ) closedir( dir_ptr );
  60. if ( fd != NULL ) fclose( fd );
  61.  
  62. return 0;
  63. }
  64.  
  65. /* Pasa todos los caracteres de la cadena a minúsculas */
  66. char * str_to_lower( char * s ) {
  67.  
  68. size_t k = 0;
  69.  
  70. while ( s[k] != '\0' ) {
  71. if ( isalpha( s[k] ) ) s[k] = tolower( s[k] );
  72. k++;
  73. }
  74.  
  75. return s;
  76. }

Este programa es funcional, sólo necesita ser compilado y probado. Por ejemplo, yo tengo el mi directorio un file1.txt, y al pasarle el nombre 'FiLe1' me dice que lo abrió. Al pasarle 'FilE2' no lo abre, porque no tengo 'file2.txt'.

Como ves, recorremos todo el directorio y convertimos sus nombres a minúsculas usando las funciones de biblioteca isaplha() (prueba si es una letra), y tolower() (pasa una letra a minúscula).

Lo de recorrer directorio requiere conocer acerca de la estructura dirent y la función readdir. Yo escribí un post al respecto el otro foro, te invito a leerlo para comprender esto mejor: http://foro.chuidiang.com/ccplusplus-linux/listar-contenido-de-un-directorio-usando-funciones-posix-de-c/

Se esperan comentarios, opiniones, etc .....  :)
Páginas: 1 ... 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 [21] 22 23 24 25 26
WAP2 - Aviso Legal - Powered by SMF 1.1.21 | SMF © 2006-2008, Simple Machines