Foro de elhacker.net

Programación => Programación C/C++ => Mensaje iniciado por: NOB2014 en 8 Octubre 2016, 14:54 pm



Título: Programa para revisar los errores de sintaxis de un programa en C.
Publicado por: NOB2014 en 8 Octubre 2016, 14:54 pm
Hola, muy buen día, ¿cómo están? -
Les comento, termine de estudias con el manual de COMO PROGRAMAR C C++ Y JAVA DEITEL&DEITEL-4° Edición-Español y para refrescar conceptos estoy leyendo El lenguaje de programación C - Kernighan, Ritchie, y piden que haga el siguiente programa. -

Citar
Ejercicio 1-24. Escriba un programa para revisar los errores de sintaxis rudimen­
tarios de un programa en C, como paréntesis, llaves y corchetes no alineados. No
olvide las comillas ni los apóstrofos, las secuencias de escape y los comentarios.
(Este programa es difícil si se hace completamente general.)

La primera duda que tengo es ¿pondrían el código en una variable char o en un archivo?
Desde ya muchas gracias, saludos. -


Título: Re: Programa para revisar los errores de sintaxis de un programa en C.
Publicado por: ivancea96 en 8 Octubre 2016, 15:51 pm
Sería ideal cargar el código a una cadena. Así pues, el código puede estar inicialmente en un archivo si quieres: luego, lo cargas y listo.
Trabajar directamente con el archivo sería más lento y algo más complejo.
Y por memoria no habrá problema. Un código dificilmente va a ocupar más de 1 MB.


Título: Re: Programa para revisar los errores de sintaxis de un programa en C.
Publicado por: NOB2014 en 8 Octubre 2016, 16:42 pm
Hola.
Decirme si lo que pienso hacer es una forma correcta, cuento con getchar() el total de caracteres que tiene el archivo y luego con este dato reservo memoria dinámica para cargarlo en precisamente en memoria ¿es una buena alternativa?. -
Saludos.


Título: Re: Programa para revisar los errores de sintaxis de un programa en C.
Publicado por: ivancea96 en 8 Octubre 2016, 23:41 pm
Para saber el tamaño del archivo, posicionas el cursor al final (con fseek y SEEK_END, por ejemplo), y luego obtienes la posición con ftell.


Título: Re: Programa para revisar los errores de sintaxis de un programa en C.
Publicado por: NOB2014 en 9 Octubre 2016, 00:14 am
Código
  1. if( ptrArchivo != NULL ){
  2. fseek(ptrArchivo,0,SEEK_END);
  3. tamanio = ftell(ptrArchivo);
  4. fclose( ptrArchivo );
  5. }else{
  6. printf( "\n ERROR - el archivo no se pudo abrir..." );
  7. exit(EXIT_FAILURE);
  8. }

Ahora me quiero ver con el resto. - :huh: :huh: :huh:
Saludos.


Título: Re: Programa para revisar los errores de sintaxis de un programa en C.
Publicado por: NOB2014 en 9 Octubre 2016, 23:39 pm
Hola, muy buen Domingo.
Tengo un problema con la función cargarArchivoMemoria (línea 36)no sé en que estoy fallando pero no me vuelca el contenido del fichero en la memoria, me podrían decir donde estoy fallando, leí, busque, practique pero debo recurrir a Uds. porque no lo logro. - 

El programa:

Código
  1. #include <stdio.h>
  2. #include <stdlib.h>
  3.  
  4. long int tamanioArchivo( FILE *ptrArchivo, long int tamanio );
  5. char *cargarArchivoMemoria( FILE *ptrArchivo, long int tamanio, char *archivoMem );
  6. void corrector( long int tamanio, char *archivoMem );
  7.  
  8. int main( int argc, char **argv ){
  9. FILE *ptrArchivo = NULL;
  10. long int tamanio = 0;
  11. char *archivoMem = NULL;
  12.  
  13. ptrArchivo = fopen("corregir.c", "r+t");
  14.  
  15. if( ptrArchivo != NULL ){
  16. tamanio = tamanioArchivo( ptrArchivo, tamanio );
  17. archivoMem = cargarArchivoMemoria( ptrArchivo, tamanio, archivoMem );
  18. corrector( tamanio, archivoMem );
  19. free( archivoMem );
  20. fclose( ptrArchivo );
  21. }else{
  22. printf( "\n ERROR - el archivo no se pudo abrir..." );
  23. exit(EXIT_FAILURE);
  24. }
  25.  
  26. return EXIT_SUCCESS;
  27. }
  28.  
  29. long int tamanioArchivo( FILE *ptrArchivo, long int tamanio ){
  30. fseek(ptrArchivo,0,SEEK_END);
  31. tamanio = ftell(ptrArchivo);
  32.  
  33. return tamanio;
  34. }
  35.  
  36. char *cargarArchivoMemoria( FILE *ptrArchivo, long int tamanio, char *archivoMem ){
  37. int i=0;
  38. archivoMem = (char *)calloc( tamanio, sizeof(char) );
  39.  
  40. if( archivoMem != NULL ){
  41. while( !feof(ptrArchivo) ){
  42. *(archivoMem+i) = fgetc( ptrArchivo );
  43. i++;
  44. }
  45. }else{
  46. printf( "\n ERROR - Fallo la asignación de memoria..." );
  47. exit(EXIT_FAILURE);
  48. }
  49.  
  50. return archivoMem;
  51. }
  52.  
  53. void corrector( long int tamanio, char *archivoMem ){
  54. int i;
  55. for( i=0; i<tamanio; i++ ){
  56. printf("%d", *(archivoMem+i) );
  57. }
  58. }

El archivo a copiar:

Código
  1. #include <stdio.h>
  2.  
  3. int main( void ){
  4.  
  5. printf( "\n Hola mundo\n\n" );
  6.  
  7. return 0;
  8.  
  9. }

Gracias y un abrazo. -


Título: Re: Programa para revisar los errores de sintaxis de un programa en C.
Publicado por: geeke en 10 Octubre 2016, 00:11 am
Debes colocar el indicador de posición al comienzo del fichero nuevamente

Código
  1. long int tamanioArchivo( FILE *ptrArchivo, long int tamanio )
  2. {
  3.    fseek(ptrArchivo,0,SEEK_END);
  4.    tamanio = ftell(ptrArchivo);
  5.    rewind(ptrArchivo); //volver al inicio
  6.    return tamanio;
  7. }


Título: Re: Programa para revisar los errores de sintaxis de un programa en C.
Publicado por: NOB2014 en 10 Octubre 2016, 02:07 am
Hola, geeke, muchas gracias por ocuparte. -
Me voy a dar un fuerte tirón de orejas, a esta altura no me debería ocurrir estos errores tan de primer grado. -

Saludos.


Título: Re: Programa para revisar los errores de sintaxis de un programa en C.
Publicado por: MAFUS en 10 Octubre 2016, 17:10 pm
Tu función cargarArchivoMemoria no está bien diseñada.  En ella pasas como argumento archivoMem que resulta ser una declaración de una variable local de la función. Si retornas el dato a través del retorno de la función deberías quitar ese argumento de la llamada y transformarlo en declaración de variable local.
Si lo quieres como argumento de llamada deberías pasarlo por referencia (puntero a puntero) y modificarlo bien dentro de la función. Entonces puedes devolver el puntero a la cadena como valor de retorno u otra cosa para indicar éxito o fallo de la función.


Título: Re: Programa para revisar los errores de sintaxis de un programa en C.
Publicado por: NOB2014 en 10 Octubre 2016, 19:00 pm
Hola, MAFUS.
Si amigo muchas gracias por la aclaración, cuando tengas un ratito de tiempo revisarla, por favor, para saber si ahora está correcto, dejo todo el código para que se fijen en la función en la línea 55, parece que da resultados correctos, lo hice de esta manera para no utilizar mil if o un switch. - 
En cuanto a las barras invertida antes de la " y \ es porque me daba error y parece que no las tiene en cuenta como un elemento mas. -

Código
  1. #include <stdio.h>
  2. #include <stdlib.h>
  3.  
  4. long int tamanioArchivo( FILE *ptrArchivo, long int tamanio );
  5. char *cargarArchivoMemoria( FILE *ptrArchivo, long int tamanio );
  6. void corrector( long int tamanio, char *archivoMem );
  7.  
  8. int main( int argc, char **argv ){
  9. FILE *ptrArchivo = NULL;
  10. long int tamanio = 0;
  11. char *archivoMem = NULL;
  12.  
  13. ptrArchivo = fopen("corregir.c", "r+t");
  14.  
  15. if( ptrArchivo != NULL ){
  16. tamanio = tamanioArchivo( ptrArchivo, tamanio );
  17. archivoMem = cargarArchivoMemoria( ptrArchivo, tamanio );
  18. corrector( tamanio, archivoMem );
  19. free( archivoMem );
  20. fclose( ptrArchivo );
  21. }else{
  22. printf( "\n ERROR - el archivo no se pudo abrir..." );
  23. exit(EXIT_FAILURE);
  24. }
  25.  
  26. return EXIT_SUCCESS;
  27. }
  28.  
  29. long int tamanioArchivo( FILE *ptrArchivo, long int tamanio ){
  30. fseek(ptrArchivo,0,SEEK_END);
  31. tamanio = ftell(ptrArchivo);
  32. rewind(ptrArchivo);
  33.  
  34. return tamanio;
  35. }
  36.  
  37. char *cargarArchivoMemoria( FILE *ptrArchivo, long int tamanio ){
  38. int i=0;
  39. char *archivoMem = NULL;
  40. archivoMem = (char *)calloc( tamanio, sizeof(char) );
  41.  
  42. if( archivoMem != NULL ){
  43. while( !feof(ptrArchivo) ){
  44. *(archivoMem+i) = fgetc( ptrArchivo );
  45. i++;
  46. }
  47. }else{
  48. printf( "\n ERROR - Fallo la asignación de memoria..." );
  49. exit(EXIT_FAILURE);
  50. }
  51.  
  52. return archivoMem;
  53. }
  54.  
  55. void corrector( long int tamanio, char *archivoMem ){
  56. int i,j, operUno[16] = {0}, linea=1;
  57. char c, *operDos = "\"#.(){}[]<>;,=/\\";
  58.  
  59.  
  60. for( i=0; i<tamanio; i++ ){
  61. c = *(archivoMem+i);
  62. if( c != '\n' ){
  63. for( j=0; j<16; j++ ){
  64. if( c == *(operDos+j) ){
  65. operUno[j] += 1;
  66. }
  67. }
  68. }else{
  69. linea++;
  70. }
  71. }
  72.  
  73. for( j=0; j<16; j++ ){
  74. printf("\n %c = %d", *(operDos+j) , operUno[j] );
  75. }
  76. }

Saludos.


Título: Re: Programa para revisar los errores de sintaxis de un programa en C.
Publicado por: MAFUS en 10 Octubre 2016, 19:53 pm
Vale , ahora dos cosas más, tres:
calloc es un poco lenta puew además de adquirir memoria la pone a 0. Como llenas toda esta memoria con el contenido del archivo no hace falta ponerla a 0, por tanto puedes usar malloc.

Ya qu adquieres memoria con malloc deberías liberarla, es una buena práctica,  despues de usarla. En main debes usar free para liberar archivoMem.

De igual forma tienes abierto un archivo en ptrArchivo. Debes liberarlo cuando termines de usarlo con fclose.


Título: Re: Programa para revisar los errores de sintaxis de un programa en C.
Publicado por: NOB2014 en 10 Octubre 2016, 20:13 pm
Lo que me sugieres que haga no está contemplado en las lineas 19 y 20.


Título: Re: Programa para revisar los errores de sintaxis de un programa en C.
Publicado por: MAFUS en 10 Octubre 2016, 22:50 pm
Tienes razón  :rolleyes: No lo vi.


Título: Re: Programa para revisar los errores de sintaxis de un programa en C.
Publicado por: NOB2014 en 10 Octubre 2016, 23:23 pm
Tengo casi todo preparado para hacer lo más importante que es corregir errores de sintaxis pero ete aquí que no se me cae una misera idea, preguntarle si hay algo escrito como un tutorial sobre el tema ni lo pienso porque busque bastante en internet y nada, salvo que aya buscado equivocadamente. -
Les dejo una pregunta para tratar de que me den un empujoncito para comenzar, si la primera línea es:
Código
  1. include <stdio.h>
Como harían para encontrar el error. -

Saludos.


Título: Re: Programa para revisar los errores de sintaxis de un programa en C.
Publicado por: ivancea96 en 10 Octubre 2016, 23:49 pm
Es algo complicado.
C no trabaja con comprobaciones sin más. Diría que es más como un autómata finito.
Cuando dudes, fíjate en las salidas que generaría tu compilador:
Código
  1. a < b >
Da error: expected '=', ',', ';', 'asm' or '__attribute__' before '<' token

Ha encontrado un nombre que no es una palabra reservada, y espera una de esas cadenas después.

Hombre, no es por ponerte trabas, pero hacer un analizador de C para todos los casos es complicado. Tendrás que tener un montón de palabras y construcciones en cuenta y estudiar a fondo las estructuras que posee.
Una cosa es verificar los comentarios, llaves, corchetes, parantesis y comillas, y otra ya es analizar cada palabra xd


Título: Re: Programa para revisar los errores de sintaxis de un programa en C.
Publicado por: geeke en 11 Octubre 2016, 16:03 pm
Les dejo una pregunta para tratar de que me den un empujoncito para comenzar, si la primera línea es:
Código
  1. include <stdio.h>
Como harían para encontrar el error. -

En primer lugar en el enunciado del ejercicio no se menciona detectar este tipo de errores, te aconsejo resolver primero lo propuesto luego intentar ir mas alla. Te puedo dar una idea de como lo puedes encarar, lo que puedes hacer es usar contadores para cada caso establecerlos a cero. Luego por ejemplo si encuentras una llave de apertura incrementar el contador correspondiente y decrementarlo si encuentras una llave de cierre, posteriormente verificar el contador

Saludos


Título: Re: Programa para revisar los errores de sintaxis de un programa en C.
Publicado por: NOB2014 en 11 Octubre 2016, 18:53 pm
Hola a todos. -
Gracias Iván por tu participación, siempre con buen aporte, geeke tienes toda la razón me estaba yendo por las ramas, me diste un impulso importante ya que estaba por dejarlo por un tiempo seguir con el libro y retomarlo luego ya que continuar con esto me va a dar mucho conocimiento, bueno a pensar y practicar, a una última cosa, debería tener mucha mala suerte si encuentro un código entre comillas con un solo paréntesis y si ocurre habrá que darse idea, tal vez cuando encuentre comillas dobles debería saltar hasta encontrar la siguiente comillas. -

Código
  1. printf( "\n Hola (mundo\n\n" );

Saludos


Título: Re: Programa para revisar los errores de sintaxis de un programa en C.
Publicado por: ivancea96 en 11 Octubre 2016, 19:42 pm
Las comillas las puedes tratar como cualquier paréntesis o llave. Las únicas diferencias, es que se abre y se cierra con el mismo símbolo, y la más importante: cuando haya una comilla, ignorarás los paréntesis, llaves y corchetes que haya hasta que se cierren las comillas de nuevo.

Ten en cuenta también, los caracteres de escape. Por ejemplo:
Código
  1. "abc\"sdf"

O un pelín más complejo:
Código
  1. "abc\\"
  2. "abc\\\"sdf"


Título: Re: Programa para revisar los errores de sintaxis de un programa en C.
Publicado por: NOB2014 en 12 Octubre 2016, 20:04 pm
Hola a todos. -
Continuando con mi proyecto me encuentro con la necesidad de guardar la línea donde se encuentra por Ej. una apertura de llave para luego si encuentro un cierre de la misma poner el contador a cero en el correspondiente elemento del vector contador(geeke), pero si no encuentro el cierre de la misma es un error y debo mostrar el mensaje y una referencia en que línea se encuentra el mismo, para ello tengo que utilizar memoria dinámica ya que si bien conozco la cantidad de columnas no así la cantidad de filas (renglones), porque puede ocurrir que haya 3 aperturas de llaves y luego se encontrarían los cierre de las mismas (o no) y de no ser así necesito las referencias de las líneas donde se encuentran. -
Hasta aquí me parece que estoy bien rumbado pero la cuestión es que no sé cómo hacer una tabla con memoria dinámica, para un arreglo lo hice de esta manera(código a continuación) y todo funciona pero para un matriz no me doy idea y no pude encontrar ejemplos en internet, encontré algunos pero es sabiendo de antemano las filas y las columnas. -

   (http://i66.tinypic.com/vx22dw.png)

Código
  1. void ingreso( void ){
  2. size_t ingresos, contador = 0, n, ok, ch;
  3. int *numeros = NULL, *mas_numeros = NULL;
  4.  
  5. do{
  6. do{
  7. printf( "\n Ingrese un numero entero (0 para finalizar).....: " );
  8. ok = scanf( "%lu", &ingresos ) == 1 && ingresos >= 0;
  9. while( (ch = getchar()) != EOF && ch != '\n');
  10.  
  11. if( ok == 0 ){
  12. printf( "\n El ingreso es incorrecto, intentelo nuevamente...\n\n\t");
  13. printf("Pulse una tecla para continuar..." ); getchar();
  14. }
  15.  
  16. }while( !ok );
  17.  
  18. contador++;
  19. mas_numeros = (int*)realloc(numeros, contador * sizeof(int));
  20.  
  21. if( mas_numeros != NULL ){
  22. numeros = mas_numeros;
  23. numeros[contador-1] = ingresos;
  24. }
  25. else{
  26. safeFree( numeros );
  27. puts( "Error en asignar memoria....." );
  28. exit(1);
  29. }
  30. }while( ingresos != 0 );
  31.  
  32. limpiarPantalla();
  33.  
  34. printf ("\n Numeros introducidos.....: ");
  35. for( n=0; n < contador - 1; n++ )
  36. printf( "%d ",numeros[n] );
  37.  
  38. ordenar( contador, numeros );
  39.  
  40. safeFree( numeros );
  41. }
  42.  
Espero como siempre deseen ayudarme.-
Saludos.


Título: Re: Programa para revisar los errores de sintaxis de un programa en C.
Publicado por: NOB2014 en 13 Octubre 2016, 16:13 pm
Hola, ¿cómo están?
Parece que lo logré, el programa que dejo es para practicar es obvio que podía haber asignado toda la memoria de una vez y esta de más aclararles que utilizo un arreglo de una dimensión como si fuera de dos.

Código
  1. #include <stdio.h>
  2. #include <stdlib.h>
  3.  
  4.  
  5. int main( int argc, char **argv ){
  6. int fil=1, col=5, i, j, x=col, *tmp=NULL ;
  7. int a[] = {33,18,5,2,19,306,202,88,31,64};
  8. int *ptrArr = (int *)malloc( fil*col*sizeof(int) );
  9.  
  10. if( ptrArr != NULL ){
  11. fil++;
  12. x += col;
  13.  
  14. tmp = (int *)realloc( ptrArr, x );
  15. if( tmp != NULL ){
  16. ptrArr = tmp;
  17. tmp = NULL;
  18. x=0;
  19. for( i=0; i<fil; i++ ){
  20. for( j=0; j<col; j++ ){
  21. ptrArr[fil*i+j] = a[x];
  22. printf( "%3d ", ptrArr[fil*i+j] );
  23. x++;
  24. }
  25. printf("\n");
  26. }
  27. }else{
  28. printf( "\n No se pudo reasignar memoria" );
  29. return EXIT_FAILURE;
  30. }
  31. }else{
  32. printf( "\n No se pudo reservar memoria" );
  33. return EXIT_FAILURE;
  34. }
  35.  
  36. free( ptrArr );
  37. ptrArr = NULL;
  38.  
  39. return EXIT_SUCCESS;
  40.  
  41. }
  42.  
Saludos.


Título: Re: Programa para revisar los errores de sintaxis de un programa en C.
Publicado por: geeke en 15 Octubre 2016, 15:38 pm
Tienes dos errores importantes en tu ultimo codigo:

- Primero, la notacion fil * i + j no accede al array como 2D, esto sobreescribe en cada iteracion del bucle externo lo asignado previamente, puedes comprobar esto imprimiendo el array a parte, lo que buscas es i * col + j.

- Segundo, solo reservas espacio para siente enteros no para diez, afortunadamento solo logras asignar siente enteros al array debido al error mencionado, caso contrario estarias desbordando el array.



Título: Re: Programa para revisar los errores de sintaxis de un programa en C.
Publicado por: NOB2014 en 15 Octubre 2016, 17:55 pm
Hola, geeke, ¿cómo estas? -
El primer error totalmente de acuerdo, en el segundo casi no tengo dudas que estoy equivocado porque desde que participas en mis post todo lo tuyo fueron aciertos, pero igual tengo la siguiente duda:
x en la línea 6 se iguala a col que vale 5, o sea, que para mí en la línea 8 reserva memoria para 5 enteros, luego en la línea 12 a la variable x le sumo col por lo tanto en la línea 14 x vale 10 y para mi criterio reservo memoria para 10 enteros, me podías decir en que estoy equivocado. -
Saludos.


Título: Re: Programa para revisar los errores de sintaxis de un programa en C.
Publicado por: geeke en 15 Octubre 2016, 19:44 pm
pero igual tengo la siguiente duda:
x en la línea 6 se iguala a col que vale 5, o sea, que para mí en la línea 8 reserva memoria para 5 enteros, luego en la línea 12 a la variable x le sumo col por lo tanto en la línea 14 x vale 10 y para mi criterio reservo memoria para 10 enteros, me podías decir en que estoy equivocado. -
Saludos.

No olvides que realloc reserva memoria en bytes, esto quiere decir que estas reasignando solo diez bytes, es decir espacio para dos enteros mas, teniendo en cuenta que un int es equivalente a cuatro bytes en un sistema de 32 bits. Por eso es importante no olvidar multiplicar size * sizeof(int).

Saludos.