Foro de elhacker.net

Programación => Programación C/C++ => Mensaje iniciado por: NOB2014 en 6 Abril 2014, 21:16 pm



Título: Prioridad y asociatividad de los operadores en C. (Programa propio)
Publicado por: NOB2014 en 6 Abril 2014, 21:16 pm
Hola a todos y que tengan un muy buen día.-
Por el enunciado se darán cuenta de lo que deseo hacer, si me dejan ser prejuicio muchos dirán que ganas de complicarse por algo que el compilador de C lo efectúa perfectamente, si bien esto es cierto tengo mucha fe que este hilo me proporcionara mucho conocimiento (intuición, corazonada).-
Lo primero que deseo hacer es poner en una variable int (9 - 2) y borrarlo de la variable cadena, si bien logro extraer la cadena con un inicio correcto pero no logro el corte en el último paréntesis.-
Por último ¿lo harian de otra manera?.-     

Código
  1. #include <stdio.h>
  2. #include <string.h>
  3.  
  4. int main(){
  5. char cadena[100] = "3 * 5 + (9 - 2) + 5", *enc = NULL;
  6.  
  7. enc = strchr(cadena, '(');
  8.  
  9. printf("\n %s", enc);
  10.  
  11. printf("\n\n");
  12. return 0;
  13. }

Saludos y desde ya muchas gracias.
Daniel


Título: Re: Prioridad y asociatividad de los operadores en C. (Programa propio)
Publicado por: leosansan en 6 Abril 2014, 23:14 pm

Lo que me gusta del C es su minimalismo: por qué usar funciones que tu te puedes crear, pasando de las librerías correspondientes  ;):

Citar

 9 - 2


Código
  1. #include <stdio.h>
  2.  
  3. int main(){
  4.  int i,j,i0,i1;
  5.  char cadena[100] = "3 * 5 + (9 - 2) + 5", cadena1[100];
  6.  for (i=0;cadena[i]; i++){
  7.    if (cadena[i]=='(')
  8.      i0=i;
  9.    if (cadena[i]==')'){
  10.      i1=i;
  11.      break;
  12.    }
  13.  }
  14.  for (i=i0+1,j=0;i<i1; i++,j++)
  15.    cadena1[j]=cadena[i];
  16.  cadena1[j]='\0';
  17.  printf("\n %s", cadena1);
  18.  printf("\n\n");
  19.  return 0;
  20. }

¡¡¡¡ Saluditos! ..... !!!!


(http://st.forocoches.com/foro/images/smilies/aaaaa.gif)


Título: Re: Prioridad y asociatividad de los operadores en C. (Programa propio)
Publicado por: NOB2014 en 7 Abril 2014, 00:19 am
Hola a todos.
Bueno pude lograr un avance pero no consigo insertar el resultado de auxiliar en cadena, créanme que estuve practicando pero me atrevo a pedirle ayuda un tanto apresurado por que estoy ansioso por avanzar.-

Código
  1. #include <stdio.h>
  2. #include <stdlib.h>
  3.  
  4. int main(){
  5. int i, j, inicio, final;
  6. char cadena[100] = "3 * 5 + (9 - 2) + 5", auxiliar[100];
  7.  
  8. for (i=0;cadena[i]; i++){
  9. if (cadena[i]=='(')
  10. inicio=i;
  11. if (cadena[i]==')'){
  12. final=i;
  13. break;
  14. }
  15. }
  16.  
  17. for (i=inicio+1,j=0;i<final; i++,j++){
  18. auxiliar[j]=cadena[i];
  19. }
  20.  
  21. j = final - inicio;
  22. for(i=inicio; i < inicio+j+1 ; i++){
  23. cadena[i] = ' ';
  24. }
  25.  
  26. auxiliar[j]='\0';
  27.  
  28. printf("\n auxiliar = %s  cadena = %s", auxiliar, cadena);
  29.  
  30. printf("\n\n");
  31. return 0;
  32. }

Saludos.
Daniel
 


Título: Re: Prioridad y asociatividad de los operadores en C. (Programa propio)
Publicado por: rir3760 en 7 Abril 2014, 02:49 am
El primer cambio que debes hacer es almacenar el '\0' en el array "auxiliar" justo después del segundo bucle y para sustituir la cadena entre paréntesis por espacios el tercer bucle es demasiado complicado.

Con los cambios:
Código
  1. #include <stdio.h>
  2.  
  3. int main(void)
  4. {
  5.   int i, j, inicio, final;
  6.   char cadena[100] = "3 * 5 + (9 - 2) + 5", auxiliar[100];
  7.  
  8.   for (i = 0; cadena[i]; i++){
  9.      if (cadena[i] == '(')
  10.         inicio = i;
  11.      if (cadena[i] == ')') {
  12.         final = i;
  13.         break;
  14.      }
  15.   }
  16.  
  17.   for (i = inicio + 1, j = 0; i < final; i++, j++)
  18.      auxiliar[j] = cadena[i];
  19.   auxiliar[j] = '\0';
  20.  
  21.   for (i = inicio; i <= final; i++)
  22.      cadena[i] = ' ';
  23.  
  24.   printf("auxiliar = \"%s\", cadena = \"%s\"\n", auxiliar, cadena);
  25.  
  26.   return 0;
  27. }

----

Editado: para obtener la subcadena delimitada por paréntesis mediante strchr basta con dos llamadas la primera buscando '(' y la segunda ')'. Por ejemplo:
Código
  1. #include <stdio.h>
  2. #include <string.h>
  3.  
  4. int main(void)
  5. {
  6.   char *s = "3 * 5 + (9 - 2) + 5";
  7.   char *p;
  8.   char *q;
  9.  
  10.   if ((p = strchr(s, '(')) && (q = strchr(p, ')')))
  11.      printf("%.*s\n", (int) (q - p + 1), p);
  12.  
  13.   return 0;
  14. }
Eso para imprimir la subcadena en la salida estándar, para almacenarla en un array basta con sustituir printf por sprintf.

Un saludo


Título: Re: Prioridad y asociatividad de los operadores en C. (Programa propio)
Publicado por: NOB2014 en 7 Abril 2014, 15:42 pm
Hola a todos.
rir3760 lo estoy haciendo de esta manera porque lo tuyo me gusta muchísimo porque es más conciso, pero no logro todavía implementarlo, lo que me trae ahora es que alguien me diga cómo puedo poner el operador en una variable como la operador luego lo pondré en un arreglo para con un if establecer el correspondiente.-         

Saludos.
Daniel



Código
  1. #include <stdio.h>
  2. #include <stdlib.h>
  3.  
  4. int main(void){
  5. int i, j, inicio, final, resultado = 0;
  6. char cadena[100] = "3 * 5 + (9 + 2) + 5", auxiliar[100] = {'\0'}, auxUno[2] = {'\0'}, auxDos[2] = {'\0'}, operador[2] = {'\0'};
  7.  
  8. for (i = 0; cadena[i]; i++){
  9. if (cadena[i] == '(')
  10. inicio = i;
  11. if (cadena[i] == ')') {
  12. final = i;
  13. break;
  14. }
  15. }
  16.  
  17. for (i = inicio + 1, j = 0; i < final; i++, j++)
  18. auxiliar[j] = cadena[i];
  19.  
  20. auxiliar[j] = '\0';
  21. operador[0] = auxiliar[2]; operador[1] = '\0';
  22. auxUno[0] = auxiliar[0]; auxUno[1] = '\0';
  23. auxDos[0] = auxiliar[4]; auxDos[1] = '\0';
  24. resultado = atoi(auxUno) - atoi(auxDos);
  25. printf("\n %d", resultado);
  26.  
  27. for (i = inicio; i <= final; i++)
  28. cadena[i] = ' ';
  29.  
  30.  
  31. return 0;
  32. }


Título: Re: Prioridad y asociatividad de los operadores en C. (Programa propio)
Publicado por: leosansan en 8 Abril 2014, 15:52 pm
...................................................
...........lo que me trae ahora es que alguien me diga cómo puedo poner el operador en una variable como la operador luego lo pondré en un arreglo para con un if establecer el correspondiente.-    ......................... ....................


Lo primero es lo primero y es ni más ni menos que eliminar de la subcadena auxiliar los espacios en blanco, que luego la lían parda. Esto lo consigues con una pequeña modificación en tu código:

Código
  1. for (i = inicio + 1, j = 0; i < final; i++)
  2.    if (cadena[i]!=' '){
  3.    auxiliar[j] = cadena[i];
  4.    j++;
  5.    }
  6. auxiliar[j] = '\0';
  7.  printf("\n%s\n", auxiliar);

Lo segundo es que a priori estableces que los números se compongan de un solo dígito, cuando podrían estar formados por varios dígitos y ya te fastidiarían las cuentas de dónde está el signo,etc. Esto lo puedes arreglar con:

Código
  1. i=0;
  2.  for (j=0,k=0;auxiliar[j];j++){
  3.    if (isdigit(auxiliar[j])){
  4.      aux[k][i]=auxiliar[j];
  5.      i++;
  6.    }
  7.    if (!isdigit(auxiliar[j])){
  8.      op=auxiliar[j];
  9.      aux[k][i]='\0';
  10.      i=0,k++;
  11.    }
  12.  }
  13.  aux[k][i]='\0';

Y lo del operador, que lo pillas en el trozo de código anterior en op, basta con usar una variable char op que guarde el tipo de operación y luego en un switch seleccionarla de forma automática. Algo como:

Código
  1. switch(op){
  2.    case'+':resultado = atoi(aux[0]) + atoi(aux[1]);
  3.    break;
  4.    case'-':resultado = atoi(aux[0]) - atoi(aux[1]);
  5.    break;
  6.    case'*':resultado = atoi(aux[0]) * atoi(aux[1]);
  7.    break;
  8.    case'/':resultado = atoi(aux[0]) / atoi(aux[1]);
  9.    break;
  10.    /******* y mas *******/
  11.  }
  12.  printf("\nRESULTADO: %d", resultado);

Y ya tendrías una salida como esta, con la segunda linea de código:

Código
  1. char cadena[100] = "3 * 5 + (1 5 * 2 5  0) + 5", auxiliar[100] = {'\0'}, aux[10][10] = {'\0'}, op;

Citar

15*250

RESULTADO: 3750



Queda mucho por hacer, por ejemplo que exista más de  una operación, que los números sean decimales, etc. Pero todo se va andando despacito.

Salu2!.


Título: Re: Prioridad y asociatividad de los operadores en C. (Programa propio)
Publicado por: NOB2014 en 8 Abril 2014, 19:35 pm
Hola leo.
Que puedo decir del trabajo que te tomaste para corregir casi todo el código y además documentarlo, muchas pero muchas gracias.-
Me pongo de inmediato a tratar de implementarlo y luego te/les haré consulta de las cosas que me queden dudas.-

Citar
Una sugerencia para Eternal Idol, me parece que sería conveniente que cuando se modifica el post se obligue a poner una pequeña descripción del motivo, leí a primera hora de la mañana(Argentina) lo que posteo leo y luego encuentro “Última modificación: Hoy a las 16:57 por leosansan” y me interesaría saber que modificó, creo que me/nos ayudaría a comprender  más fácilmente el contenido del mismo, sólo una sugerencia que tal vez ni llegues a leer.-

Saludos.
Daniel


Título: Re: Prioridad y asociatividad de los operadores en C. (Programa propio)
Publicado por: leosansan en 8 Abril 2014, 20:03 pm
Citar
Una sugerencia para Eternal Idol, me parece que sería conveniente que cuando se modifica el post se obligue a poner una pequeña descripción del motivo, leí a primera hora de la mañana(Argentina) lo que posteo leo y luego encuentro “Última modificación: Hoy a las 16:57 por leosansan” y me interesaría saber que modificó, creo que me/nos ayudaría a comprender  más fácilmente el contenido del mismo, sólo una sugerencia que tal vez ni llegues a leer.-

Aclaro la modificación.

En el primer código en borrador que hice no elimine los espacios en blanco de la cadena auxiliar por lo que aparecía la línea:


Código
  1. if (!isdigit(auxiliar[j]) && auxiliar[j]!=' ' ){

Me dí cuenta que los espacios en blanco engorrinaban el código y surgió el código que colgué donde los eliminaba previamente de la cadena auxiliar. Pero con las prisas se me olvidó que entonces el:

Código
  1. && auxiliar[j]!=' '

Estaba de más, no mal, de más. Al verlo por la tarde me dí cuenta y lo corregí eliminando y dejando la línea como:

Código
  1. if (!isdigit(auxiliar[j])){

Una corrección menor por lo que no puse el mensaje de EDITADO que pongo cuando cambio algo sustancial. Yo al menos hago eso, para que quede constancia.

Espero haber aclarado las posibles dudas que planteaban en el comentario.

Salu2!.


EDITO: Además del error de un nuevo post, sorry, sorry, la mayor parte de las ediciones son meras correcciones ortográficas, como la de ahora en que tenía puesto dnde en lugar de donde.


Título: Re: Prioridad y asociatividad de los operadores en C. (Programa propio)
Publicado por: Eternal Idol en 8 Abril 2014, 20:10 pm
NOB2014: yo lo leo pero soy un moderador unicamente, si queres plantealo al STAFF en el subforo de "Sugerencias y dudas sobre el Foro". Igual calcula que si obligas a poner un texto, siempre se puede poner algo inutil igual (como "editar por editar"), con lo cual la opcion y la obligacion terminan siendo lo mismo.


Título: Re: Prioridad y asociatividad de los operadores en C. (Programa propio)
Publicado por: NOB2014 en 8 Abril 2014, 20:36 pm
Hola a todos.-
Leo, espero que no me hayas mal interpretado, lo mío era tan solo una sugerencia y te tomé como  referencia porqué fue una idea del momento, lo que decís Eternal es muy cierto pero a alguien como Uds. que hacen una tarea tan loable e impagable disponiendo tanto tiempo al servicio de los demás sin más no creo que se les cruce por la cabeza el hecho  de mentir, no por lo menos en este ámbito.-       

Saludos.
Daniel


Título: Re: Prioridad y asociatividad de los operadores en C. (Programa propio)
Publicado por: Eternal Idol en 8 Abril 2014, 20:57 pm
Hola a todos.-
Leo, espero que no me hayas mal interpretado, lo mío era tan solo una sugerencia y te tomé como  referencia porqué fue una idea del momento, lo que decís Eternal es muy cierto pero a alguien como Uds. que hacen una tarea tan loable e impagable disponiendo tanto tiempo al servicio de los demás sin más no creo que se les cruce por la cabeza el hecho  de mentir, no por lo menos en este ámbito.-      

Saludos.
Daniel


No, seguro, pero los mismos usuarios pueden editar sus mensajes, por cierto ahora que lo veo no hay una opcion de mensaje o me confundi con otro foro o no existe, de ser lo ultimo te invito a que hagas la sugerencia en el subforo correspondiente, es buena.


Título: Re: Prioridad y asociatividad de los operadores en C. (Programa propio)
Publicado por: NOB2014 en 9 Abril 2014, 16:55 pm
Hola a todos.
rir3760, espero me puedas explicar lo de la foto, no puedo encontrar la teoría suficiente y me parece de suma importancia aprender este trozo de sintaxis.-

(http://i59.tinypic.com/15n2iw9.jpg)

Saludos.
Daniel   


Título: Re: Prioridad y asociatividad de los operadores en C. (Programa propio)
Publicado por: leosansan en 9 Abril 2014, 20:46 pm
Hola a todos.
rir3760, espero me puedas explicar lo de la foto, no puedo encontrar la teoría suficiente y me parece de suma importancia aprender este trozo de sintaxis.-

...........................................


No soy rir pero intentaré hacerlo lo mejor posible. ;)

La ini del final del sprintf indica desde que posición se van a incorporar los caracteres a la variable aux, mientras que (int) (fin - ini +1) da el total de caracteres que, a partir de la posición mencionada por ini, se añaden a aux.

Por ejemplo, para tener la salida:



Citar
9 - 2

usaría:

Código
  1. #include <stdio.h>
  2. #include <string.h>
  3.  
  4. int main(void){
  5.  char *s = "3 * 5 + (9 - 2) + 5",aux[10]={'\0'};
  6.  char *ini,*fin;
  7.  if ((ini = strchr(s, '(')) && (fin = strchr(ini, ')')))
  8.    sprintf(aux,"\n%.*s\n", (int) (fin - (ini +1)), ini+1);
  9.  printf("%s",aux);
  10.  return 0;
  11. }

¡¡¡¡ Saluditos! ..... !!!!


(http://st.forocoches.com/foro/images/smilies/aaaaa.gif)






Título: Re: Prioridad y asociatividad de los operadores en C. (Programa propio)
Publicado por: NOB2014 en 10 Abril 2014, 23:51 pm
Hola a todos.-
Leo, en primer lugar agradecerte por la explicación, de esa manera lo entendí perfectamente.-
Lo que me trae ahora es: cómo puedo hacer  para que la variable op se comporte como la macro  MAS algo como.

Código
  1. #include <stdio.h>
  2. #include <stdlib.h>
  3. #include <ctype.h>
  4. #include <string.h>
  5.  
  6. #define MAS +
  7.  
  8. int main(void){
  9. char *cadena = "3 * 5 + (9 - 2) + 5", auxiliar[100]={'\0'}, aux[10][10], *inicio=NULL, *final=NULL, op;
  10. int i=0, longitud=0, j=0, resultado=0, k=0;
  11.  
  12. if ((inicio = strchr(cadena, '(')) && (final = strchr(inicio, ')'))){
  13. longitud = sprintf(auxiliar,"%.*s", (int) (final - (inicio +1)), inicio+1);
  14. for(; i<longitud; i++){
  15. if (auxiliar[i]!=' '){
  16. auxiliar[j] = auxiliar[i];
  17. j++;
  18. }
  19. }
  20. auxiliar[j] = '\0';
  21.  
  22. }
  23.  
  24. i=0;
  25. for (j=0,k=0;auxiliar[j];j++){
  26. if (isdigit(auxiliar[j])){
  27. aux[k][i]=auxiliar[j];
  28. i++;
  29. }
  30. if (!isdigit(auxiliar[j])){
  31. op=auxiliar[j];
  32. aux[k][i]='\0';
  33. i=0,k++;
  34. }
  35. }
  36. aux[k][i]='\0';
  37.  
  38. switch(op){
  39. case'+':resultado = atoi(aux[0]) + atoi(aux[1]);
  40. break;
  41. case'-':resultado = atoi(aux[0]) - atoi(aux[1]);
  42. break;
  43. case'*':resultado = atoi(aux[0]) * atoi(aux[1]);
  44. break;
  45. case'/':resultado = atoi(aux[0]) / atoi(aux[1]);
  46. break;
  47. case'%':resultado = atoi(aux[0]) % atoi(aux[1]);
  48. break;
  49. }
  50. printf("\n resultado = %d", resultado);
  51.  
  52. i = k = -5;
  53. i = i MAS k;
  54. printf("\n resultado = %d", i);
  55.  
  56. printf("\n\n");
  57. return 0;
  58. }

resultado = atoi(aux[0]) MAS atoi(aux[1]);   

Espero que Uds. tengan alguna manera porque practiqué y busque en google y no puedo hallar la solución.-
 

Saludos.
Daniel


Título: Re: Prioridad y asociatividad de los operadores en C. (Programa propio)
Publicado por: leosansan en 11 Abril 2014, 14:25 pm

Te funciona sin problemas:

Código
  1. i = k = -5;
  2. i = i MAS k;
  3.  
  4.  
  5. seria:-5+(-5)=-10  O.K

En tu código y con macros sería:

Código
  1. case'+':resultado = atoi(aux[0]) MAS atoi(aux[1]);
  2.  break;
  3. case'-':resultado = atoi(aux[0]) MENOS atoi(aux[1]);
  4. ................................................

¡¡¡¡ Saluditos! ..... !!!!


(http://st.forocoches.com/foro/images/smilies/aaaaa.gif)



Título: Re: Prioridad y asociatividad de los operadores en C. (Programa propio)
Publicado por: NOB2014 en 11 Abril 2014, 15:57 pm
Hola a todos.
Leo no me interpretaste correctamente, lo que quiero hacer es reemplazar esta parte de tú código:

Código
  1. switch(op){
  2. case'+':resultado = atoi(aux[0]) + atoi(aux[1]);
  3. break;
  4. case'-':resultado = atoi(aux[0]) - atoi(aux[1]);
  5. break;
  6. case'*':resultado = atoi(aux[0]) * atoi(aux[1]);
  7. break;
  8. case'/':resultado = atoi(aux[0]) / atoi(aux[1]);
  9. break;
  10. case'%':resultado = atoi(aux[0]) % atoi(aux[1]);
  11. break;
  12. }

Por algo como lo que pongo a continuación, voy a poner un ejemplo sólo como referencia (por supuesto no es la correcta).-

Código
  1. int operador[]={+,-,*,/,%};
Y llamarlo desde op

Espero que haya quedado más claro.-

Saludos y un abrazo.
Daniel


Título: Re: Prioridad y asociatividad de los operadores en C. (Programa propio)
Publicado por: rir3760 en 13 Abril 2014, 15:38 pm
lo que quiero hacer es reemplazar esta parte de tú código:

Código
  1. switch(op){
  2. case'+':resultado = atoi(aux[0]) + atoi(aux[1]);
  3. break;
  4. case'-':resultado = atoi(aux[0]) - atoi(aux[1]);
  5. break;
  6. case'*':resultado = atoi(aux[0]) * atoi(aux[1]);
  7. break;
  8. case'/':resultado = atoi(aux[0]) / atoi(aux[1]);
  9. break;
  10. case'%':resultado = atoi(aux[0]) % atoi(aux[1]);
  11. break;
  12. }

Por algo como lo que pongo a continuación, voy a poner un ejemplo sólo como referencia (por supuesto no es la correcta).-

Código
  1. int operador[]={+,-,*,/,%};
Y llamarlo desde op
Si entiendo correctamente lo que buscas es una función similar a eval (http://www.w3schools.com/jsref/jsref_eval.ASP) de javascript para evaluar una expresión almacenada en una cadena.

En C no existe tal función, debes implementarla de forma manual con una sentencia por cada operador como vienes haciendo y para el caso puedes revisar los temas sobre evaluación de expresiones sencillas (hay varios temas relacionados en la base de datos de los foros, solo es cuestión de utilizar el motor de búsqueda).

Un saludo