Mostrando las entradas con la etiqueta C. Mostrar todas las entradas
Mostrando las entradas con la etiqueta C. Mostrar todas las entradas

miércoles, 14 de febrero de 2018

Contar el total de repeticiones de una palabra en archivo | Programas en C



Ya había pensado en compartir los programas en C y demás programas en otros lenguajes de programación que me dejaban en la facultad, pero, por alguna razón no lo había hecho.

Les comparto ahora un programa en C, que cuenta el total de repeticiones de una palabra dentro de un archivo de texto.

Aquí el código:

#include <stdio.h> #include <string.h> #include <ctype.h> #define MAXCHAR 1000 int main() { FILE *fp; char cad_arch[MAXCHAR]; char* nom_archivo = "prueba.txt"; char cad_buscar[30], palabra_extraida[20]; int i = 0, j = 0, contador = 0; printf("Ingresa la palabra a buscar: "); scanf("%s", cad_buscar); fp = fopen(nom_archivo, "r"); if (fp == NULL){ printf("No se puede abrir el archivo %s", nom_archivo); return 1; } printf("\n\t\t--- Contenido del archivo ---\n\n"); while (fgets(cad_arch, MAXCHAR, fp) != NULL){ printf("%s", cad_arch); for (i = 0; i < strlen(cad_arch); i++){ while (i < strlen(cad_arch) && !isspace(cad_arch[i]) && isalnum(cad_arch[i])){ palabra_extraida[j++] = cad_arch[i++]; } if(j != 0){ palabra_extraida[j] = '\0'; if (strcmp(palabra_extraida, cad_buscar) == 0){ contador++; } j = 0; } } } printf("\nTotal de coincidencias: %d\n", contador); fclose(fp); return 0; }

Se usan funciones básicas de las librerías para cadenas y comparaciones.

El archivo puede contener este tipo de palabras y oraciones:

.hola hola .hola hola .hola hola -hola hola holis, adios, no, lo, hola hola
1, 1, 2, 3 hola
.hola h
fin hola
-hola,
-hola,
hol
holamundo
-hola, mundo

El archivo de ejemplo, se busca la palabra hola, y es posible contarla incluso, si hay comas, puntos, guiones o algún otro caracter especial.

La imagen es un ejemplo de ejecución.

miércoles, 30 de noviembre de 2016

GaussJordan en C



Cuando estudias programación, posiblemente uno de los programas básicos que te pedirán es el de GaussJordan, o tal vez no, pero como sea, aquí les comparto uno que desarrollé cuando lo necesité.

Es bastante simple, utiliza memoria dinámica para todo el cálculo y además si no encuentra solución pues envía un mensaje que no lo hay.

Hay muchas cosas que se necesitan pulir, por ejemplo, si ingresan más 20 ecuaciones, a veces se cicla. Claro, hay programas mucho más complejos que ya resuelven este problema, pero cuando a uno se lo piden, pues no es tan simple desarrollarlo.

El código es el siguiente, el cual solo se copia, se pega a un documento de texto y se compila con c, en mi caso utilizo geany para eso:

/* Autor: Fernando Merino
 * Programa: Método de Gauss-Jordan
 * Descripción: El método de Gauss-Jordan soluciona sistemas de ecuaciones
 * simultáneas.
 * */

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

void gausJordan(float **matriz,int n,float *raices);
void imprimirMatriz(float *raices,int n);
void leerValores(float **matriz,int n);

int main(){
 int n;
 float **matriz,*raices;
 printf("Ingrese el número de ecuaciones (n): ");
 scanf("%d",&n);
 getchar();
 matriz=(float**) malloc (sizeof (float*)*n);
 raices=(float*) malloc (sizeof (float*)*n);
 leerValores(matriz,n);
 gausJordan(matriz,n,raices);
 printf("Solución \n\n");
 imprimirMatriz(raices,n);
 getchar();
 return 0;
}
void imprimirMatriz(float *raices,int n){
 int i;
 for(i=0;i<n;i++){
  printf("X%d = %f\n",i+1,raices[i]);
 }
}
void gausJordan(float **matriz,int n,float *raices){
 int i,j,k;
 float termino;
 for(i=0;i<n;i++){
  if(matriz[i][i]==0.0){
   fprintf(stderr,"Error: División entre 0:: No hay solución!!!\n\n");
   system("pause");
   return ;
  }
  for(k=0;k<n;k++){
   if(k!=i){
    termino=matriz[k][i]/matriz[i][i];
    for(j=0;j<=n;j++){
     matriz[k][j]-=termino*matriz[i][j];
    }
   }
  }
 }
 for(i=0;i<n;i++){
  termino=matriz[i][n]/matriz[i][i];
  raices[i]=termino;
 } 
}
void leerValores(float **matriz,int n){
 int i,j;
 for(i=0;i<n;i++){
  matriz[i]=(float*) malloc (sizeof(float)*(n+1));
  for(j=0;j<n;j++){
   printf("Ingrese coeficiente de 'X%d' de la ecuación %d: ",j+1,i+1);
   scanf("%f",&matriz[i][j]);
  }
  printf("Ingrese el resultado de la ecuación %d ",i+1);
  scanf("%f",&matriz[i][n]);
 }
}


Ahora, lo que le trato de implementar, es muestre los resultados en fracciones, todo el proceso, es decir, que se le ingrese algo así 1/4, y que así se lo lleve en todo el proceso, y que al final de un resultado en fracciones. Si alguien ya lo tiene por ahí y que sea en C, y quiera compartirlo, me parecería perfecto, esto más por hobbie. Gracias y espero que les sirva.

domingo, 7 de febrero de 2016

Compilando archivos de GTK, Vala y C desde Geany


Compilar archivos es tedioso cuando se hace desde la terminal, sobre todo si hay que indicar una larga lista de bibliotecas adiciobales, como por ejemplo, allegro, lncurses, gtk, etc. 

Compilar ye ejecutarlo desde un solo editor tan solo danto clic en un sólo botón sería más simple y más fácil. Econtré un editor en el que se puede hacer eso, claro hay que configurarlo primero, y es Geany.

Geany es un editor para diferentes lenguajes de programación, pero para el que más se utiliza es C, o C++, gtk, vala, etc.

Instalar geany en Fedora es con el siguiente comando:
sudo dnf -y install geany

Configurar Genay para compilar archivos .c utilizando gtk dentro del código de c, se configura de la siguiente manera. Ir a la barra de herramientas como se muestra en la siguiente imagen:

Obviamente hay que instalar gtk-devel para desarrollar y compilar en gtk.
 

Ahora, agregar las sentencias:
`pkg-config --cflags --libs gtk+-2.0`
Al final de los campos de Compile y Build. Como se muestra en la imagen siguiente.


Para compilar archivos gtk utilizando archivos .vala, primero es necesario instalar vala-devel además de instalar gtk, ya sea en la versión gtk+2 o 3.
Luego modificar los comandos de compilar en geany.
Agregar la instrucción:
--pkg gtk+-3.0
o agregar la versión de gtk que estén utilizando.


A partir de ahora ya pueden compilar con un solo clic desde geany. Siempre tendrán la opción de la terminal. Pero pues, es solo una opción desde geany, ya saben lo que dicen, en gustos se rompen géneros.

jueves, 8 de enero de 2015

Algoritmo de Cesar

En criptografía, el cifrado César, también conocido como cifrado por desplazamiento, código de César o desplazamiento de César, es una de las técnicas de cifrado más simples y más usadas. Es un tipo de cifrado por sustitución en el que una letra en el texto original es reemplazada por otra letra que se encuentra un número fijo de posiciones más adelante en el alfabeto. Por ejemplo, con un desplazamiento de 3, la A sería sustituida por la D (situada 3 lugares a la derecha de la A ), la B sería reemplazada por la E, etc. Este método debe su nombre a Julio César, que lo usaba para comunicarse con sus generales. Más información.
#include <stdio.h>
#include <math.h>
#include <stdlib.h>
#include <ctype.h>
#include <string.h>

int main(){
 int i, c, factor;
 char cadena[200];
 printf("Ingrese una cadena: ");
 scanf(" %[^\n]s", cadena);
 printf("Ingrese un factor: ");
 scanf(" %d", &factor);
 printf("La cadena es %s\n", cadena);
 
    for(i=0; cadena[i]!='\0'; i++){
  c = cadena[i];
  if((c + factor) >= 96 && (c + factor) <= 122){
   c = c + factor;
   printf("%c",c);
  }else{
   if( (c + factor) > 122){
    c = c - 26;
    c = c + factor;
    printf("%c",c);
   }else{
    printf("%c",c);
   }
  }
 }
 return 0;
}

sábado, 1 de noviembre de 2014

Un blog con programas en C

Estaba buscando en la web un blog en el que hubiese al menos 50 de los programas que más nos piden los profesores en las materias de programación estructurada, tenía pensando hacer los programas y pegarlos en mi blog, pero encontré este: http://cprogrammingcodes.blogspot.mx/ aquí pueden encontrar más de 200 programas que usualmente nos solicitan los profesores en las clases que se lleven programación estructurada en c.

Si no han cerrado el blog tienen suerte y copien mientras puedan...

viernes, 24 de octubre de 2014

Sistema de control Takagi-Sugeno en C

/*
 * Autor: A. L. I. Fernando Merino
 * Nombre del archivo: sistemaTakgi.c
 * Descripción: Simula un sistema difuso, usando el método de Takgi-Sugeno
 * genera un archivo con los  puntos en pares (x,y) para graficar en gnuplot,
 * si desean graficar adicionalmente los puntos que estén utilizando generen
 * un archivo extra con los puntos y grafiquenlos, para comparar resultados
 * 24-octubre-2014*/

#include <stdlib.h>
#include <stdio.h>
#include <unistd.h>
#include <math.h>

/*define el total de comandos que se enviará a gnuplot*/
#define NUM_COMANDOS 5

void seleccionGaussiana();
double gaussiana(double c, double gama, double x);
double gaussDerecha(double c, double gama, double x);
double gaussIzquierda(double c, double gama, double x);
void graficarPuntosDesdeArchivo(char *cad, char *archivo, char *archivo1, char *archivo2);

int main(){
 printf("\n\tFunciones de Takgin-Sugeno\n");
 seleccionGaussiana();
    return 0;
}

void seleccionGaussiana(){
 FILE * puntGI = fopen("gaussIzquierda.txt", "w");
 FILE * puntGD = fopen("takagiSugeno.txt", "w");
 FILE * archivoPuntos = fopen("gaussiana.txt", "w");
 double x,cenGaus,anchoGaus,inicio, fin;
 double cenIzq,anchoIzq,cenDer,anchoDer;
 double ug=0,ugi=0,ugd=0,y1=0,y2=0,y3=0,y;
 /*datos que se pueden configurar:
  * muestreo [0,20]
  * las variables a y b se pueden leer desde teclado, a tiene que ser menor a b
  * opcionalmente también se puede especificar el perido de muestreo*/
 printf("Ingrese los siguientes datos:\n");
 printf("Inicio de la muestra: ");
 scanf("%lf",&inicio);
 printf("Fin de la muestra: ");
 scanf("%lf",&fin);
 printf("\nConfigure la Gaussiana Izquierda:");
 printf("\nIngresa el centro: ");
 scanf("%lf",&cenIzq);
 printf("Ingresa ancho a los lados del centro: ");
 scanf("%lf",&anchoIzq);
 
 printf("\nConfigure la Gaussiana central:");
 printf("\nIngresa el centro: ");
 scanf("%lf",&cenGaus);
 printf("Ingresa ancho a los lados del centro: ");
 scanf("%lf",&anchoGaus);
 
 printf("\nConfigure la Gaussiana derecha:");
 printf("\nIngresa el centro: ");
 scanf("%lf",&cenDer);
 printf("Ingresa ancho a los lados del centro: ");
 scanf("%lf",&anchoDer);
 
 for(x=inicio;x<=fin;x+=0.01){
  /*obtiene el valor de las membresías de cada valor de x*/
  ugi = gaussIzquierda(cenIzq,anchoIzq,x);
  ug = gaussiana(cenGaus,anchoGaus,x);
  ugd = gaussDerecha(cenDer,anchoDer,x);
  /*obtiene las y*/
  y1=0.214285714*x+2.642857143;
  y2=-0.416666667*x+0.75;
  y3=0.342857143*x-1.528571429;
  /*se susitituye en la fórmula final*/
  y=((ugi*y1)+(ug*y2)+(ugd*y3))/(ugi+ug+ugd);
  /*se guarda en un arhivo de texto con los puntos (x,y)*/
  fprintf(puntGD, "%lf %lf \n", x, y);
 }
 fclose(archivoPuntos);
 fclose(puntGD);
 fclose(puntGI);
 graficarPuntosDesdeArchivo("set title \"Graficando funciones\"",
        "plot \"takagiSugeno.txt\" using 1:2 with lines",
        "replot \"puntosAnalizar.txt\" using 1:2 with lines",
        "replot \"gaussIzquierda.txt\" using 1:2 with lines");
}

/*funciones finales de membresia*/
double gaussiana(double c, double gama, double x){
 double ux = 0, expo=0;
 expo = pow((x-c)/gama,2);
 ux = pow(2.7182818284,-0.5*expo);
 return ux;
}

double gaussIzquierda(double c, double gama, double x){
 double ux = 0, expo=0;
 expo = pow((x-c)/gama,2);
 ux = pow(2.7182818284,-0.5*expo);
 if(x<=c){
  ux=1;
 }
 return ux;
}

double gaussDerecha(double c, double gama, double x){
 double ux = 0, expo=0;
 expo = pow((x-c)/gama,2);
 ux = pow(2.7182818284,-0.5*expo);
 if(x&gtc){
  ux=1;
 }
 return ux;
}

void graficarPuntosDesdeArchivo(char *cad, char *archivo, char *archivo1, char *archivo2){
 int i;
 /*lista de comandos para ejecutar y configurar la visualización que tendrán
     * los puntos en la gráfica con gnuplot*/
    char * configGnuplot[] = {cad, 
                                "set ylabel \"----grado de membresía---&gt\"",
                                "set xlabel \"----Universo X---&gt\"",
                                archivo,
                                archivo1,
                                archivo2
                               };
    /*Se crea una archivo de tipo popen, es una tebería IPC que se usa, para
     * ejecutar gnuplot y enviarle el archivo a graficar*/
    //FILE * ventanaGnuplot = popen("gnuplot -persist", "w");
    FILE * ventanaGnuplot = popen("gnuplot -persist", "w");
    // Executing gnuplot commands one by one
    for (i=0;i<NUM_COMANDOS;i+ +){
  fprintf(ventanaGnuplot, "%s \n", configGnuplot[i]);
 }
}

viernes, 10 de octubre de 2014

Graficar puntos en Gnuplot desde C


En ocasiones es necesario realizar gráficas de alguna función o simplemente la graficación de puntos. Ésta tarea es simple de realizar desde gnuplot, suponiendo que se use alguna distro de linux. En algunos casos es necesario usar algún programa o software intermedio para realizar dicha gráfica, tal podría ser el caso de realizar un programa en c, y desde ahí generar los puntos y automáticamente graficarlos.
Cuando es la primera vez que se hace esto es un poco complicado. Aquí les traigo un ejemplo para ir comenzando con esto:
/*http://umencs.blogspot.mx/2013/05/plotting-creating-graphs-in-c-c.html File Name: GraphPlotting.c*/
/*
 * Autor: gXfer
 * Nombre del archivo: graficarGnuplotDesdeC.c
 * Descripción: Grafica en gnuplot los puntos ordeandos e inicializados 
 * en los arreglos (valoresX, valoresY)
 * 10-octubre-2014*/

#include <stdlib.h>
#include <stdio.h>
#include <unistd.h>
#define NUM_PUNTOS 11
#define NUM_COMANDOS 4

int main(){
    // X, Y valores de los puntos a graficar
    double valoresX[NUM_PUNTOS] = {0.0, 1.0, 1.0, 1.5, 2.0, 2.5, 3.0, 3.5, 4.0, 4.5, 5.0};
    double valoresY[NUM_PUNTOS] = {4.0, 4.0, 0.0, 1.0, 0.0, 1.5, 0.0, 1.0, 0.0, 0.5, 0.0};
    register int i=0;
    /* se crea y se abre el archivo puntosGraficar.txt en modo escritura 
     * para almacenar los valores de x y y que están declarados en los arreglos
     * valoresX y valoresY*/
    FILE * archivoPuntos = fopen("puntosGraficar.txt", "w");

    /*Guardar los puntos x,y en el archivo de texto creado y abierto previamente*/
    for (i=0;i<NUM_PUNTOS;i+ +){
  fprintf(archivoPuntos, "%lf %lf \n", valoresX[i], valoresY[i]);
 }
 
    /*lista de comandos para ejecutar y configurar la visualización que tendrán
     * los puntos en la gráfica con gnuplot*/
    char * configGnuplot[] = {"set title \"gXfer Graficando puntos - unir con líneas\"", 
                                "set ylabel \"----grado de membresía--->\"",
                                "set xlabel \"----Universo X--->\"",
                                "plot \"puntosGraficar.txt\" using 1:2 with lines"
                               };

    /*Se crea una archivo de tipo poen, es una tebería IPC que se usa, para
     * ejecutar gnuplot y enviarle el archivo a graficar*/
    FILE * ventanaGnuplot = popen ("gnuplot -persist", "w");
    // Executing gnuplot commands one by one
    for (i=0;i<NUM_COMANDOS;i+ +){
  fprintf(ventanaGnuplot, "%s \n", configGnuplot[i]);
 }
 fclose(archivoPuntos);
    return 0;
}

Si usas geany para compilar y ejecutar tus códigos en C, es necesario hacer las siguientes configuraciones: 
Ir a la opción construir y seleccionar de la lista desplegable la opción que dice "Establecer comandos de construcción" como se muestra en la siguiente imagen.

Abrirá una ventana como se muestra en la imagen de abajo, en la opción que dice "Compilar" deben agregar la sintaxis "-lm" sin comillas, lo mismo deben de hacer en la línea de que dice "Construir", agregar "-lm" sin comillas. y listo, le dan en aceptar y pueden compilar como normalmente lo hace.


Para compilar: ir al directorio que ha sido guardado previamente:
gcc -Wall graficarGnuplotDesdeC.c -lm -o graficarGnuplotDesdeC
Para ejecutar el resultado introduce en la línea de comandos:
./graficarGnuplotDesdeC.c

La salida es la siguiente:



Si tienen dudas no olviden comentar.

martes, 12 de agosto de 2014

Matrices dinámicas en C

No explicaré qué se hace en cada paso, sólo le mostrare el código que tengo, y ustedes se encargarán de analizarlo y modificarlo a su conveniencias. Bueno el código es el siguiente.

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

void llenarMatriz(int ** mat, int filas, int columnas);
void imprimirMatriz(int ** mat, int filas, int columnas);
void crearMatrizDinamica(int ** mat, int filas, int columnas);
void liberarMemoria(int ** array, int nrows);

int main(void){
 int nrows,ncols;
 int** array;
 // Define the size of the array at run time
 printf("Ingrese el numero de filas y colunmas: ");
 scanf("%d %d",&nrows,&ncols);
 
 array=(int**)malloc(nrows*sizeof(int*));
 
 crearMatrizDinamica(array,nrows,ncols);
 llenarMatriz(array,nrows,ncols);
 imprimirMatriz(array,nrows,ncols);
 liberarMemoria(array,nrows);
 return 0;
}

void liberarMemoria(int ** array, int nrows){
 int i;
 for (i=0; i<nrows; i++){
  free((void*)array[i]);
 }
 free((void*)array);
}

void crearMatrizDinamica(int ** mat, int filas, int columnas){
 int i;
 for (i=0; i<filas; i++)
  mat[i]=(int*)malloc(columnas*sizeof(int));
}
void llenarMatriz(int ** mat, int filas, int columnas){
 int i,j;
 for(i=0;i<filas;i++){
  for(j=0;j<columnas;j++){
   mat[i][j]=i+1+j;
  }
 }
}

void imprimirMatriz(int ** mat, int filas, int columnas){
 int i,j;
 for(i=0;i<filas;i++){
  for(j=0;j<columnas;j++){
   printf("-%d-",mat[i][j]);
  }
  printf("\n");
 }
}

viernes, 11 de julio de 2014

Punteros en programas arduino

Recientemente realicé un proyecto con arduino. Necesitaba que al tener presionado un botón desde el protoboard conectado a un pin de arduino se encendiera un led, pero que únicamente validara el primer pulso sobre el botón.
Un programa en arduino se ejecuta en loop, es decir en un ciclo infinito, para detener un proceso se usan retardos, esto con la función delay(100), el parámetro que recibe son el total de milisengundos que se retardará le programa.
El problema que tuve en primer lugar es cómo validar únicamente el primer pulso, e ignorar los demás pulsos, lo que ocurre es que arduino sensa los pines cada 100 milisegundos, al menos ese es el tiempo que yo le dí, entonces cada 100 ms realizaba la misma acción, algo que no quería.
EL segundo problema fue usar apuntadores.
La solución quedó de la siguiente manera:
Primero vea el circuito y el material que usé para esta parte:

Ahí pueden ver los materiales usados, así como la conexión de cada componente. La idea es que cuando se presione un botón se encienda el led de salida, solo tomando en cueta el primer pulso, es decir, tanto en pantalla como en el resultado solo mostrará un uno sólo una vez.
El código es el siguiente:

const int buttonPinEntrada1 = 2;
const int buttonPinEntrada2 = 3;
const int ledPinSalida1 =  8;
const int ledPinSalida2 =  9;
int buttonState1 = 0;
int buttonState2 = 0;
int bBoton1=0;
int bBoton2=0;
int *band;

void setup(){
  Serial.begin(9600);
  pinMode(ledPinSalida1, OUTPUT);
  pinMode(ledPinSalida2, OUTPUT);
  pinMode(buttonPinEntrada1, INPUT);
  pinMode(buttonPinEntrada2, INPUT);
}

void loop(){
  /*boton 1*/
  buttonState1 = digitalRead(buttonPinEntrada1);
  band=&bBoton1;
  validarUnicoPulsoBoton(ledPinSalida1,band,buttonState1);
  /*boton 2*/
  buttonState2 = digitalRead(buttonPinEntrada2);
  band=&bBoton2;
  validarUnicoPulsoBoton(ledPinSalida2,band,buttonState2);
  delay(100);
}

/*procedimiento que se usa para validar una sola pulsacion de un boton*/
void validarUnicoPulsoBoton(int ledPinSalida,int *band,int buttonState){
  /*se verifica si el estado del buton es igual a uno, es decir, si esta presionado, de tal forma que si el boton se mantiene presionado
  por mucho tiempo, pasara la siguiente condicion, esto evita que se realize la misma accion muchas veces*/
  if(buttonState == 1){
    /*se veirifica si la bandera de ese boton esta desactivada, lo que significa que no se ha realizado ninguna accion
    tras a ver pulsado dicho boton*/
    if(*band == 0){
      /*se realiza la accion, en este caso se enciende un led*/
      digitalWrite(ledPinSalida, HIGH);
      /*se actualiza la bandera para indicar que la accion ya se ha realizado al menos una vez*/
      *band=1;
      /*se imprime en pantalla el valor de la bandera, solo para asegurar en que estado se encuentra (opcional)*/
      Serial.println(*band);
    }
  }
  /*se verifica si el estado del boton es igual a cero, esto indicara que el boton ha cambiado de valor, presionado a no presionado*/
  if(buttonState == 0){
    /*se valida que la bandera sea igual a 1, indica que la accion que se realiza cuando es presionado el boton se ha realizado al menos
    una vez*/
    if(*band == 1){
      /*sin la bandera esta activada, en este caso se encendio el led, entonces es necesario apagarlo*/
      digitalWrite(ledPinSalida, LOW);
      /*se actuliza el valor de la bandera, para indicar que el  estado del boton ha sido actualizado*/
      *band=0;
      /*opcional se imprime el nuevo valor de la bandera*/
      Serial.println(*band);
    }
  }
}

Y eso es todo, buena suerte.