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


 


Tema destacado: Java [Guía] Patrones de diseño - Parte 1


  Mostrar Temas
Páginas: [1] 2
1  Programación / Programación C/C++ / [APORTE] conio.h mínimo para Llinux en: 29 Mayo 2017, 11:06
Es frecuente en este foro encontrarse con gente que sigue trabajando con TurboC de Borland con la líbrería conio.h y normalmente la usan para dos o tres funciones: gotoxy, getch y getche. Para los que trabajamos con Linux nos da un poco de pereza ir editando todas esas líneas para hacer el código ejecutable. Pues bien, a raíz de eso he decidido hacerme una pequeña conio para quitarme de encima susodicho trabajo y ahora quiero compartirla con vosotros.

conio.h
Código
  1. #ifndef CONIO_PARA_LINUX
  2. #define CONIO_PARA_LINUX
  3.  
  4. #include <stdio.h>
  5. #include <termios.h>
  6.  
  7. void gotoxy(int x, int y) {
  8.    printf("\33[%d;%df", y, x);
  9. }
  10.  
  11. static char getch_interno(int eco) {
  12.    char c;
  13.    struct termios old, new;
  14.  
  15.    tcgetattr(0, &old);
  16.    new = old;
  17.    new.c_lflag &= ~ICANON;
  18.    new.c_lflag &= eco ? ECHO : ~ECHO;
  19.    tcsetattr(0, TCSANOW, &new);
  20.    c = getchar();
  21.    tcsetattr(0, TCSANOW, &old);
  22.  
  23.    return c;
  24. }
  25.  
  26. char getch() {
  27.    return getch_interno(0);
  28. }
  29.  
  30. char getche() {
  31.    return getch_interno(1);
  32. }
  33.  
  34. #endif
2  Programación / Programación C/C++ / TIP: para limpiar el buffer de entrada en: 29 Abril 2016, 13:19
Intentando responder a un post y, como siempre pruebo el código de mi respuesta antes, necesitaba de una forma genérica una instrucción para limpiar el buffer de entrada stdin después de adquirir una cadena de entrada mediante fgets.

fgets, según el largo de la cadena introduce saca de stdin el carácter '\n' o no y si se usa while (getchar() != '\n'); sin que haya un carácter de nueva línea en el buffer el programa se detiene y espera a que el usuario introduzca algo. Y eso no queda bien.. Por otra parte controlar a mano si hay o no un carácter de nueva línea es engorroso y ensucia el código.

Llegué a la siguiente solución. Necesita de la librería string.h.

Código
  1. #include <string.h>
  2.  
  3. #define clrfstr(X) { \
  4.     if(!strchr((X), '\n')) \
  5.         while(getchar() != '\n'); \
  6. }

Esto vacía, o no, stdin dependiendo de si ha la cadena ingresada contiene, o no, el carácter de nueva línea.

El código se debe incluir justo después de fgets o de la función que se haya usado para adquirir la cadena. X es el argumento que representa a la variable cadena adquirida.
3  Programación / Programación C/C++ / [C] Estructuras con miembros privados. en: 21 Abril 2016, 23:45
Como digo esto se trata de C y no de C++.

Es posible emular, en C, el comportamiento de miembros privados de datos definidos por el programador, al estilo de la POO, para que los usuarios de esa estructura no puedan acceder directamente a los datos que hay dentro de ella.

Las ventajas que tiene esta técnica:
1. El usuario no puede modificar los datos directamente y deben pasar por los filtros que imponga el programador.
2. El programador puede cambiar los datos internos que tiene la estructura y su interfaz (funciones getters y setters) sin que el usuario tenga que recompilar todo su código para hacer uso de estas modificaciones.

Los inconvenientes:
1. Sólo se puede situar la estructura en memoria del montón con lo que aparece el problema de la fragmentación de la memoria
2. La memoria se debe liberar ya sea mediante free o una función que proporcione el programador a modo de destructor.

Aquí va el código:


dato.h
Código
  1. #ifndef __DATO_H__
  2. #define __DATO_H__
  3.  
  4. typedef struct __dato__ DATO;
  5.  
  6. DATO* new_dato();
  7. void delete_dato(DATO* objeto);
  8. int get_dato(DATO* objeto);
  9. void set_dato(DATO* objeto, int valor);
  10.  
  11. #endif


dato.c
Código
  1. #include <stdlib.h>
  2. #include "dato.h"
  3.  
  4. struct __dato__ {
  5.    int miembro_privado;
  6. };
  7.  
  8. DATO* new_dato() {
  9.    DATO* d = malloc(sizeof(DATO));
  10.    d->miembro_privado = 0;
  11.    return d;
  12. }
  13.  
  14. void delete_dato(DATO* objeto) {
  15.    free(objeto);
  16. }
  17.  
  18. int get_dato(DATO* objeto) {
  19.    return objeto->miembro_privado;
  20. }
  21.  
  22. void set_dato(DATO* objeto, int valor) {
  23.    objeto->miembro_privado = valor;
  24. }



Ahora el cliente:

main.c
Código
  1. #include <stdio.h>
  2. #include "dato.h"
  3.  
  4. int main() {
  5.    DATO *d;
  6.  
  7.    d = new_dato();
  8.    set_dato(d, 5);
  9.    printf("%i\n", get_dato(d));
  10.  
  11.    /* d->miembro_privado = 4; /* <- Esto va a fallar */
  12.    /* printf("%i\n", get_dato(d)); */
  13.  
  14.    delete_dato(d);
  15.  
  16.    return 0;
  17. }
4  Foros Generales / Noticias / BASH Ubuntu sobre Windows 10... nativo en: 31 Marzo 2016, 09:44
What the?

Pues sí, los chicos de Canonical han portado BASH de su Linux a Windows 10 y éste ejecuta el entorno de forma nativa, como si fuera el propio Linux.
Este BASH viene con todo lo que se podría esperar de él: awk, sed, grep, vi, etc. y junto al gestor de paquetes apt así que se pueden descargar paquetes como emacs.

¿Qué os parece este acercamiento?

http://www.hanselman.com/blog/DevelopersCanRunBashShellAndUsermodeUbuntuLinuxBinariesOnWindows10.aspx
5  Foros Generales / Sugerencias y dudas sobre el Foro / [SOLUCIONADO] El antihack de la página es demasiado restrictivo en: 8 Marzo 2016, 09:32
Ya va dos veces que intento realizar una respuesta en el foro de C/C++ y el sistema de protección me bloquea. ¿Cuáles son las nuevas reglas que espera el foro?
6  Foros Generales / Sugerencias y dudas sobre el Foro / Cambiar texto GeSHi por algo más descriptivo en: 14 Febrero 2016, 22:01
Es cierto que GeSHi es poco descriptivo y, sobre todo para la gente nueva que entra, no se pondrá a jugar con cada una de las opciones de formato antes de postear su duda así que van a dejar el código en texto llano. Yo también lo he hecho.

Por eso en vez de tener el título GeSHi, la lista desplegable debería titularse 'elige tu lenguaje...' o 'Código en lenguaje...'; o algo que a primera vista ya diera a entender que eso sirve para que el código que va dentro se va a formatear en el lenguaje que se elija.
7  Foros Generales / Sugerencias y dudas sobre el Foro / Sobre caracteres no ingleses entre las etiquetas GeSHi en los foros en: 4 Enero 2016, 18:14
Ya me había acostumbrado a que la ñ y las letras con tilde en los foros aparecen mal escritas cuándo se muestra código, pero mi sorpresa fue cuándo vi que en los mensajes privados sí se ven bien.
Por tanto esto es una sugerencia.
Por lo visto los mensajes privados y los foros están en codificaciones diferentes. Se podrían arreglar los foros para permitir tildes y la ñ.

Sí, pongo tildes en los comentarios  :rolleyes:
8  Programación / Programación C/C++ / [C] Argumentos anónimos en llamadas a funciones en: 22 Diciembre 2015, 21:48
Muy buenas.

Pues sigo con mi cruzada de autodescubrimiento de gramáticas extrañas que C acepta.

Supongamos la siguiente función que acepta un array de cadenas y las va imprimiendo hasta encontrar una cadena vacía:

Código
  1. void func(char* str[]) {
  2.    int i = 0;
  3.    while(str[i][0] != '\0')
  4.        printf("%s\n", str[i++]);
  5. }

Ante esto uno piensa que para llamar a dicha función debe crear una variable de esta forma
Código
  1. char *lista[] = {"uno", "dos", "tres", "cuatro", "");
y después llamar a la función
Código
  1. func(lista);

Pues se puede llamar a la función pasando un argumento anónimo, la lista entera directamente, de esta forma
Código
  1. func((char*[]){"uno", "dos", "tres", "cuatro", ""});

Obviamente, como siempre, esto se puede modificar al gusto y necesidades de cada uno.

Un programa de prueba completo es este:
Código
  1. #include <stdio.h>
  2.  
  3. void func(char* str[]) {
  4.    int i = 0;
  5.    while(str[i][0] != '\0')
  6.    printf("%s\n", a[i++]);
  7. }
  8.  
  9. int main()
  10. {
  11.    func((char*[]){"uno", "dos", "tres", "cuatro", ""});
  12.    return 0;
  13. }

Ya me diréis que os parece  ;)
9  Programación / Programación C/C++ / [C] Lista dinámica de funciones en C (emulando los delegados de .NET) en: 20 Diciembre 2015, 01:38
Muy buenas.

Pues la idea es hacer algo parecido a los delegados de C# pero con el C de toda la vida.
Sobre una lista dinámica de diferentes funciones con la misma firma se puede hacer las siguientes operaciones:
· Añadir funciones al final de la lista
· Quitar la primera aparición de una función dada
· Vaciar la lista de una tacada
· Ejecutar todas las funciones de la lista de forma secuencial y con unos parámetros comunes dados en la llamada a la ejecución.

En este programa se trabaja sobre una función que acepta un char* y no devuelve nada, pero se puede modificar fácilmente para trabajar con otras funciones.

Código
  1. #include <stdio.h>
  2. #include <stdlib.h>
  3.  
  4. typedef struct tdelegate {
  5. void (*func)(char*);
  6. struct tdelegate *next;
  7. } DELEGATE;
  8.  
  9. int delegate_add(DELEGATE **pdelegate, void (*funcpointer)(char*)) {
  10. DELEGATE *newdelegate = malloc(sizeof(DELEGATE));
  11. DELEGATE *aux = NULL;
  12.  
  13. if(newdelegate == NULL)
  14. return 0;
  15.  
  16. newdelegate->func = funcpointer;
  17. newdelegate->next = NULL;
  18.  
  19. if(*pdelegate == NULL)
  20. *pdelegate = newdelegate;
  21. else {
  22. aux = *pdelegate;
  23. while(aux->next != NULL)
  24. aux = aux->next;
  25. aux->next = newdelegate;
  26. }
  27. return 1;
  28. }
  29.  
  30. void delegate_exec(DELEGATE **pdelegate, char *str) {
  31. DELEGATE *actualdelegate = *pdelegate;
  32.  
  33. while(actualdelegate != NULL) {
  34. actualdelegate->func(str);
  35. actualdelegate = actualdelegate->next;
  36. }
  37. }
  38.  
  39. void delegate_del(DELEGATE **pdelegate, void (*funcpointer)(char*)) {
  40. DELEGATE *actualdelegate = *pdelegate;
  41. DELEGATE *aux = NULL;
  42. int found = 0;
  43.  
  44. if(funcpointer == NULL || actualdelegate == NULL)
  45. return;
  46.  
  47. if(actualdelegate->func == funcpointer)
  48. {
  49. aux = actualdelegate->next;
  50. free(actualdelegate);
  51. actualdelegate = aux;
  52. }
  53. else {
  54. while(actualdelegate->next != NULL && !found) {
  55. if(actualdelegate->next->func == funcpointer) {
  56. found = 1;
  57. aux = actualdelegate->next->next;
  58. free(actualdelegate->next);
  59. actualdelegate->next = aux;
  60. }
  61. else actualdelegate = actualdelegate->next;
  62. }
  63. }
  64. }
  65.  
  66. void delegate_free(DELEGATE **pdelegate) {
  67. DELEGATE *aux = NULL;
  68.  
  69. if(*pdelegate == NULL) return;
  70. while(*pdelegate != NULL) {
  71. aux = (*pdelegate)->next;
  72. free(*pdelegate);
  73. *pdelegate = aux;
  74. }
  75. }
  76.  
  77. /* FUNCIONES DE PRUEBA */
  78. void a(char *str) {
  79. printf("%p: %s\n", &a, str);
  80. }
  81.  
  82. void b(char *str) {
  83. printf("%p: %s\n", &b, str);
  84. }
  85.  
  86. void c(char *str) {
  87. printf("%p: %s\n", &c, str);
  88. }
  89.  
  90. /* PROGRAMA DE PRUEBA */
  91. int main() {
  92.  
  93. DELEGATE *midelegado = NULL;
  94.  
  95. delegate_add(&midelegado, &a);
  96. delegate_add(&midelegado, &b);
  97. delegate_add(&midelegado, &c);
  98.  
  99. delegate_exec(&midelegado, "hola");
  100.  
  101. delegate_del(&midelegado, &b);
  102. delegate_exec(&midelegado, "adios");
  103.  
  104. delegate_free(&midelegado);
  105. midelegado = NULL;
  106.  
  107. return 0;
  108. }
  109.  
  110.  
10  Programación / Programación C/C++ / Un programa que muestra donde el S.O. pone cada cosa. en: 3 Diciembre 2015, 21:44
No es mucha cosa, solo un divertimento; pero sirve para ver en qué parte de la memoria pone el S.O. las funciones, las variables locales, las globales y las dinámicas.
Así se puede ver como el sistema separa la memoria de código, la memoria de pila (stack) y la memoria del montón (heap).

Código
  1. #include <stdio.h>
  2. #include <stdlib.h>
  3.  
  4. char gc;
  5. int gi;
  6.  
  7. int main(int argc, char *argv[])
  8. {
  9. char c;
  10. int i;
  11. int *p = malloc(sizeof(int));
  12. printf("printf\t= %p\n", &printf);
  13. printf("malloc\t= %p\n", &malloc);
  14. printf("main\t= %p\n", &main);
  15. printf("\n");
  16. printf("gi\t= %p\n", &gi);
  17. printf("gc\t= %p\n", &gc);
  18. printf("\n");
  19. printf("argv\t= %p\n", &argv);
  20. printf("argc\t= %p\n", &argc);
  21. printf("\n");
  22. printf("c\t= %p\n", &c);
  23. printf("i\t= %p\n", &i);
  24. printf("p\t= %p\n", &p);
  25. printf("\n");
  26. for(i = 0; i < argc; ++i)
  27. printf("argv[%i]\t= %p -- %s$\n", i, argv[i], argv[i]);
  28. printf("\n");
  29. printf("p (->)\t= %p\n", p);
  30. free(p);
  31. return 0;
  32. }

P. ej.:

$ ./c 1 12 123 1234 12345
printf   = 0x4004f0
malloc   = 0x400520
main   = 0x40061d

gi   = 0x60105c
gc   = 0x601060

argv   = 0x7ffd71212400
argc   = 0x7ffd7121240c

c   = 0x7ffd71212413
i   = 0x7ffd71212414
p   = 0x7ffd71212418

argv[0]   = 0x7ffd71214551 -- ./c$
argv[1]   = 0x7ffd71214555 -- 1$
argv[2]   = 0x7ffd71214557 -- 12$
argv[3]   = 0x7ffd7121455a -- 123$
argv[4]   = 0x7ffd7121455e -- 1234$
argv[5]   = 0x7ffd71214563 -- 12345$

p (->)   = 0x1e36010
Páginas: [1] 2
Aviso Legal - Powered by SMF 1.1.21 | SMF © 2006-2008, Simple Machines