Foro de elhacker.net

Programación => Programación C/C++ => Mensaje iniciado por: el_lujo en 25 Febrero 2015, 18:52 pm



Título: Simulación de Compilador Pascal
Publicado por: el_lujo en 25 Febrero 2015, 18:52 pm
Saludos, señores.

quisiera orientación sobre un problema que no puedo resolver en un programa en c/c++, el cual debo simular la primera línea del compilador pascal.

Donde tengo problemas es en la supresión de los espacios en blanco a la izquierda de la cadena, ejm.  suponiendo que la primera linea es: program NombrePrograma;

Quiero suprimir cualquier espacio en blanco que tenga esta línea a la izquierda y derecha.  Adjunto lo que he logrado en conjunto con otros compañeros.

Con ayuda de la internet, agregué una función que por sí sola suprime los espacios, pero no sé por qué no me resulta igual agregandola al código.

sé que algo esta mal pero no puedo verlo.


Gracias.

Código
  1. /*Simulacion de Pascal
  2.  
  3. */
  4.  
  5.  
  6. #include <stdio.h>  
  7. #include <stdlib.h>  
  8. #include <conio.h>
  9. #include <string.h>
  10.  
  11. void suprime(char cadena[]);
  12.  
  13. int main()
  14. {
  15. char cCad[50],cCadena[50], cPRO[8]="PROGRAM",cPRO1[8]="program";
  16.    int  TaCad,cont=0;
  17.  
  18.        system ("cls");
  19. printf("\n\t               SIMULACION COMPILADOR PASCAL \n\n");
  20.        printf ("\n1: ");gets (cCadena);
  21.  
  22.  
  23.   //=================================================================================
  24. suprime(cCadena);
  25. TaCad=strlen(cCad);
  26. if (cCad[0]=='\0')  
  27. {
  28. printf ("\n Error [Linea 1]:- Falta 'PROGRAM', 'nombre del programa' y ';' \n ");
  29. }
  30.  
  31. for ( i=0; i<=6; i++)
  32. {
  33.  
  34. if (cCad[i]!= cPRO[i])
  35. {
  36. if (cCad[i]!=cPRO1[i]) cont++;
  37. }
  38. }
  39.  
  40. if (cCad[i]==' ')
  41.  
  42. if (cont!=0 && TaCad>0)
  43. {
  44. printf ("\n Error [Linea 1]:- 'PROGRAM' esta mal escrito  \n ");
  45. }
  46.  
  47. if (cCad[7]!=' ' && cont==0 && TaCad>8)
  48. {
  49. printf ("\n Error [Linea 1]:- Falta espacio entre 'PROGRAM' y nombre de programa\n");
  50. }
  51.  
  52. if (cCad[7]!=' ' && cont!=0 && TaCad<8)
  53. {
  54. printf ("\n Error [Linea 1]:- Omision de espacio entre 'PROGRAM' Y el nombre del Programa\n");
  55. }
  56.  
  57. if  (cCad[8]==';' && cont==0 && TaCad>=7)
  58. {
  59. printf ("\n Error [Linea 1]:- Omision del nombre del programa \n\n");
  60. }
  61.  
  62. if  (cCad[8]==';' && cont==0 && TaCad==8 )
  63. {
  64. printf ("\n Error [Linea 1]:- Omision del nombre del programa \n\n");
  65. }
  66.  
  67. if  (cCad[1]==' '|| cCad[0]==';' ||cCad[8]==' ')  
  68. {
  69. printf ("\n Error [Linea 1]:- Omision del nombre del programa \n\n");
  70. }
  71.  
  72. if (cCad[7]==';' || cCad[7]=='\0' && cont==0)
  73. {
  74. printf ("\n Error [Linea 1]:- Omision del nombre del programa \n\n");
  75. }
  76.  
  77. if (cCad[TaCad-1]!=';')
  78. {
  79. printf ("\n Error [Linea 1]:- Falta El ';' al Final de la linea\n\n");
  80. }
  81.  
  82.  
  83. system ("PAUSE");
  84. }
  85.  
  86. void suprime(char cadena[])
  87. {
  88.  
  89. char cCad[100];
  90. int x=0, z=0, y=strlen(cadena);
  91.  
  92.  
  93.  
  94.  
  95. while(cadena[x]==' ')
  96. {
  97. if(cadena[x]==' ')
  98. x++;
  99. }
  100.  
  101.  
  102. while(cadena[x]!='\0')
  103. {
  104.  
  105. cCad[z]=cadena[x];
  106. x++;
  107. z++;
  108. }
  109.  
  110. }

Mod: Cuando publiques código, usa las etiquetas GeSHi


Título: Re: Simulación de Compilador Pascal
Publicado por: engel lex en 25 Febrero 2015, 20:17 pm
modifiqué tu código le puse etiquetas GeSHi, procura usarlas al publicar código

estás haciéndolo en C++ y es algo que puede ser complejo, recomiendo el uso de librerías apropiadas para ello...

Código
  1. #include <string>

y yo haría el trim así

Código
  1. string trim(string s){
  2. string::iterator i = s.begin();
  3. string::iterator f = s.end();
  4. while(*i==' ')
  5. i++;
  6.  
  7. while(*f==' ')
  8. f--;
  9.  
  10. return string(i,f);
  11. }

te ahorras un montón de código complicado y los problemas a que char sea limitado... no se olvide que es namespace std


Título: Re: Simulación de Compilador Pascal
Publicado por: el_lujo en 25 Febrero 2015, 20:41 pm
Gracias, engel lex.
Mis disculpas por mi ignorancia; no estaba claro sobre publicar códigos.  Ya lo tendré pendiente.

Sobre la ayuda que me acabas de dar, estoy muy agradecido. Mi problema es que soy novato en C/C++ y por tal razón estoy aprendiendo en la marcha.

Para estar claro, el código que me hiciste iría en la función, cierto?
Gracias y discúlpame de nuevo.


Título: Re: Simulación de Compilador Pascal
Publicado por: engel lex en 25 Febrero 2015, 20:49 pm
no iría en la función XD es la función

en lugar de
Código
  1. void suprime(char cadena[])

usas esa... luego de los includes coloca
Código
  1. using namespace std;

para que no tengas ningún problema

y te recomiendo revisar un poco sobre las variables tipo string en C++ para facilitearte el lio

a demás evita el uso de conio.h ya que no pertenece a las librerías standard



Título: Re: Simulación de Compilador Pascal
Publicado por: el_lujo en 25 Febrero 2015, 21:17 pm
Excelente.
Gracias por el consejo y por la enseñanza.

Mano a la obra.


Título: Re: Simulación de Compilador Pascal
Publicado por: el_lujo en 25 Febrero 2015, 21:48 pm
Ufff!!
engel lex, no me siento mal al reconocer que soy un burro, pero ahora estoy algo confundido.  Me confundo donde al final me retorna (i,f).

Tengo que tener en cuenta que al resultado de las eliminaciones de espacios yo pueda  tomarle el tamaño de la cadena para poder hacer las comparaciones si me faltara 'PROGRAM', 'NombreArchivo' y ';'.

*Nota: Cambié:



Código
  1. string trim(string s);

por:

Código
  1. string trim(string cadena);

Así lo tengo luego de tu ayuda:

Código
  1. /*SIMULACION DE COMPILADOR PASCAL*/
  2.  
  3. #include <stdio.h>  
  4. #include <stdlib.h>  
  5. #include <string>
  6.  
  7. using namespace std;
  8. string trim(string cadena);
  9.  
  10. int main()
  11. {
  12. char cCad[50],cCadena[50], cPRO[8]="PROGRAM",cPRO1[8]="program";
  13.    int  TaCad,cont=0;
  14.  
  15.        system ("cls");
  16. printf("\n\t               SIMULACION COMPILADOR PASCAL \n\n");
  17.        printf ("\n1: ");gets (cCadena);
  18.  
  19.  
  20. string trim(cCadena);
  21.  
  22. TaCad=strlen(cCad);
  23. if (cCad[0]=='\0')  
  24. {
  25. printf ("\n Error [Linea 1]:- Falta 'PROGRAM', 'nombre del programa' y ';' \n ");
  26. }
  27.  
  28. for ( i=0; i<=6; i++)
  29. {
  30.  
  31. if (cCad[i]!= cPRO[i])
  32. {
  33. if (cCad[i]!=cPRO1[i]) cont++;
  34. }
  35. }
  36.  
  37. if (cCad[i]==' ')
  38.  
  39. if (cont!=0 && TaCad>0)
  40. {
  41. printf ("\n Error [Linea 1]:- 'PROGRAM' esta mal escrito  \n ");
  42. }
  43.  
  44. if (cCad[7]!=' ' && cont==0 && TaCad>8)
  45. {
  46. printf ("\n Error [Linea 1]:- Falta espacio entre 'PROGRAM' y nombre de programa\n");
  47. }
  48.  
  49. if (cCad[7]!=' ' && cont!=0 && TaCad<8)
  50. {
  51. printf ("\n Error [Linea 1]:- Omision de espacio entre 'PROGRAM' Y el nombre del Programa\n");
  52. }
  53.  
  54. if  (cCad[8]==';' && cont==0 && TaCad>=7)
  55. {
  56. printf ("\n Error [Linea 1]:- Omision del nombre del programa \n\n");
  57. }
  58.  
  59. if  (cCad[8]==';' && cont==0 && TaCad==8)
  60. {
  61. printf ("\n Error [Linea 1]:- Omision del nombre del programa \n\n");
  62. }
  63.  
  64. if  (cCad[1]==' '|| cCad[0]==';' ||cCad[8]==' ')  
  65. {
  66. printf ("\n Error [Linea 1]:- Omision del nombre del programa \n\n");
  67. }
  68.  
  69. if (cCad[7]==';' || cCad[7]=='\0' && cont==0)
  70. {
  71. printf ("\n Error [Linea 1]:- Omision del nombre del programa \n\n");
  72. }
  73.  
  74. if (cCad[TaCad-1]!=';')
  75. {
  76. printf ("\n Error [Linea 1]:- Falta El ';' al Final de la linea\n\n");
  77. }
  78.  
  79.  
  80. system ("PAUSE");
  81. }
  82.  
  83. string trim(string cadena)
  84. {
  85. string::iterator i = cadena.begin();
  86. string::iterator f = cadena.end();
  87. while(*i==' ')
  88. i++;
  89.  
  90. while(*f==' ')
  91. f--;
  92.  
  93. return string(i,f);
  94. }
  95.  


Título: Re: Simulación de Compilador Pascal
Publicado por: engel lex en 26 Febrero 2015, 19:04 pm
hay un problema... string no es realmente compatible con char... la cosa es usar uno u otro, sin embargo si quieres convertir de string a char es
Código
  1. strcpy(char_variable, string_variable.c_str());


ahora a los errores en tu codigo

error 1: strlen está en la librería <cstring> que no es lo mismo que <string> (ni es directamente compatible con) declarala si quieres usar esa funcion

error 2: al main no le veo return... debe tenerlo...

error 3: pusiste string trim(cCadena) al aire en tu codigo no está haciendo nada... ella retorna un string...

error 4: no usar gets, se asume descontinuado y en standard c11 fue eliminado definitivamente, usa fgets que es el más similar (revisa como se usa) o cin (de iostream) más comodo para leer desde consola

error 5: la linea 37 hace del siguien if suyo y al estar relacionada con "i" posiblemente genere error

error 6: cCad nunca fue usado, aún así lo metes en un if

sobre mi código, veo que no lo entendiste del todo, lo comento

Código
  1. string trim(string s){//retornará un string y recibe un string
  2. string::iterator i = s.begin();//crea un "apuntador" a el inicio de la cadena
  3. string::iterator f = s.end();//crea un "apuntador" al final de la cadena
  4. while(*i==' ')//si lo que está en la posición apuntada es un espacio
  5. i++;//avanza
  6.  
  7. while(*f==' ')//ergo
  8. f--;
  9.  
  10. return string(i,f);//retorna el string que está entre las posiciones
  11.                           //de los apuntadores i y f
  12. }

lo que te decía era mudar tu codigo completo a string porque es más facil manejarlo...


resumo un pedacito de tu programa para que veas como sería haciendolo en c++ con funciones de alto nivel


Código
  1. #include <string>
  2. #include <iostream>
  3.  
  4. using namespace std;
  5. string trim(string cadena);
  6.  
  7. int main()
  8. {
  9. string cCadena;
  10.    size_t TaCad,cont=0; //equivalente a unsigned long int
  11.  
  12.    system ("cls");
  13. cout  << "\n\t               SIMULACION COMPILADOR PASCAL \n\n";
  14. cout << "\n1: ";
  15. getline(cin, cCadena);
  16. cCadena = trim(cCadena);
  17.  
  18. TaCad = cCadena.size();
  19. if(cCadena.find("PROGRAM")!=0 && cCadena.find("program")!=0){
  20. cont = 1;}
  21.  
  22. if (cont!=0 && TaCad>0)
  23. {
  24. cout << "\n Error [Linea 1]:- 'PROGRAM' esta mal escrito  \n ";
  25. }
  26. if (cCadena[7]!=' ' && cont!=0 && TaCad>8)
  27. {
  28. cout << "\n Error [Linea 1]:- Falta espacio entre 'PROGRAM' y nombre de programa\n";
  29. }
  30.  

la cosa es que necesitas saber lo basico de string (http://www.cplusplus.com/reference/string/string/?kw=string) y de iostream (http://www.cplusplus.com/reference/iostream/)


Título: Re: Simulación de Compilador Pascal
Publicado por: _Enko en 27 Febrero 2015, 15:27 pm
Un toque offtopic, pero "program" no es una sentencia obligatoria en pascal. :silbar:
Muchos programas pueden no tenerla.

Saludos.


Título: Re: Simulación de Compilador Pascal
Publicado por: el_lujo en 28 Febrero 2015, 13:02 pm
Buen día.
Pido disculpas por la demora en atender las publicaciones.

Gracias engel lex, definitivamente tienes razón.  Mi problema esta en que debo aprender más de C++.  Como decía en el principio, soy un super novato y es por eso que mi comprensión de las funciones, métodos, clases y, por supuesto mi lógica, es muy débil.

Tomaré en cuenta primero estudiar bien los string e iostream.

Gracias, _Enko por tu comentario. Tienes razón sobre el uso no obligatorio de PROGRAM. Sin embargo, como es una simulación de ese compilador se pide eso, no para hacerlo ver como obligatorio, sino para ayudarnos a encontrar estos problemas, osea uso de las cadenas, en el que ustedes, especialmente engel lex, han dado tanta ayuda.

Engel lex, luego de que comentaste los códigos comprendí mucho mejor de la lógica y cómo debe tomarse en cuenta.