[ Foro de Pascal ]

Me presento. Y un problemilla: el programa no ejecuta sentencia readln

24-Oct-2010 12:26
Fulanito de Tal
3 Respuestas

Hola. Acabo de darme de alta en este foro. Estoy haciendo el curso de Pascal de la web freepascal.es. Antes de nada quiero agradecer al autor del mismo el tiempo y trabajo que dedica a divulgar este lenguaje. Yo estoy aprendiendo mucho gracias a él y es algo que quiero decir aquí. También doy las gracias a todos los que participan en el foro ya sea preguntando o ayudando a resolver cuestiones, porque de ellos también estoy aprendiendo.
Mi primer contacto con el lenguje Pascal fue hace ya años en mis tiempos de universitario. Fue el sengundo lenguaje que conocí. Antes había estudiado por mi cuenta Basic y pensaba que todos los lenguajes era más o menos así, con su sentencia "goto" que nos permitía hacer los programas a nuestro gusto sin pensarlos mucho. Pero cuando empecé a trabajar con Pascal me quedé muy sorprendido: un códido que se ejecuta empezando por la primera sentencia y terminando por la última, con un orden. No me creía que todos los problemas se pudiesen trasladar a un código Pascal. "Habrá cosas que tendrán que resolverse por narices con un goto", pensaba yo. Pero luego me di cuenta que no. Fue para mí todo un descubrimiento.
Por circunstancias de la vida tuve que dejar de programar durante mucho tiempo. Hace un par de años volví a este mundo y aprendí Python, el lenguaje de moda, y también empecé con Prolog. Pero me acordé de Pascal, de mis viejos tiempos y decidí volver con él. Encontré la web de freepascal y empecé desde la primera lección. En estos momentos lo último que he visto ha sido el tema de las funciones y los procedimientos. Hago casi todos los ejercicios de cada tema, y aunque me van surgiendo problemas, los he ido resolviendo todos. Excepto uno, que no soy capaz, por eso os escribo, por si podeis echarme una mano.
Esta es mi pequeña historia en esto de la programación. Si os he soltado un rollo insoportable, os pido disculpas. :-)
Me gustaría también decir que cuando me di de alta puse un nombre y unos apellidos ficticios porque no me gusta dejar datos personales reales en ninguna web. Si no se puede hacer me lo decís y me doy de baja y creo una nueva cuenta.

------

Bueno, ahora voy al problema en cuestión. Se puede resumir así en una sola frase: el programa no ejecuta una sentencia readln. Es decir, tenía que pararse a esperar la entrada de un dato desde el teclado, pero no lo hace, sino que continua la ejecución hasta el final.

Ahora lo describo un poco más: Es un programa de combinatoria (calcular permutaciones, combinaciones, etc.). Está sin terminar, hay variables declaradas que no se han usado todavía y seguro que tendré que declarar más variables. Defino una función para calcular el factorial de un número. Y uso una sentencia REPEAT ... UNTIL por si el usurio al terminar quiere hacer más cálculos. Y ahí es donde aparece el problema, porque pregunto al usuario: Si quieres hacer más cálculos pulsa "s". Y luego viene la sentencia readln que asigna un valor a la variable "repetir". Pero no lo hace.  Incluso he añadido una sentencia writeln(repetir), antes del end. final para que escriba en pantalla lo que tiene almacenado en "repetir", pero no escribe nada.
He probado varias cosas, como cambiar el REPEAT ... UNTIL por un WHILE. Y sigo con el mismo problema.
He cambiado el tipo de la variable "repetir", en vez de string he puesto char. Y sigo con lo mismo. Aunque aquí ha pasado algo nuevo: cuanto el tipo está declarado como string al terminar la ejecución aparece en la siguiente linea el prompt de la terminal de linux, pero si declaro la variable como char entre el fin del programa y el prompt de linux aparece una linea en blanco.
He revisado todos los puntos y comas por si acaso.
He cambiado el readln por un read y el write por un writeln, por si había algún detalle que se me escapase pero tampoco.
Se me ocurrió pensar que como empecé a escribir el código con el editor Gedit y luego me cambié a Kate, puede ser que esa sea la causa, pero me parece raro que sea por eso.
Bueno, si podéis ayudarme os lo agradezco. Seguro que es una chorrada que se me escapa.
Os vuelvo a pedir disculpas por el rollo que suelto cuando escribo. :-)

Aquí está el código (lo adjunto también como archivo porque con un editor es más facil de leer):

program combinatoria;

uses crt;

var
  conjunto, subconjunto:integer;
  opcion:byte;
  repetir:string;

function factorial(num:integer):integer;
  var
     bucle,auxiliar:integer;
  begin
     auxiliar:=1;
     for bucle:=1 to num do
        begin
           auxiliar:=auxiliar*bucle;
        end;
     factorial:=auxiliar;
  end;


begin
  repeat//por si se quiere repetir el programa
     clrscr;
     writeln('        COMBINATORIA');//presentacion del menu
     writeln('        ============');
     writeln;
     writeln('             Menu');
     writeln('-------------------------------');
     writeln('1: Permutaciones');
     writeln('2: Permutaciones con repeticion');
     writeln('3: Variaciones');
     writeln('4: Variaciones con repeticion');
     writeln('5: Combinaciones');
     writeln('6: Combinaciones con repeticion');
     writeln;
     
     repeat//para que la opcion elegida sea correcta
        gotoxy(17,13);
        write('                    ');
        gotoxy(1,13);
        write('Opcion elegida: ');
        read(opcion);
     until (opcion >= 1) and (opcion <= 6);//fin until opcion
     
     write('Si quieres hacer mas calculos pulsa "s" ');
     readln(repetir);
  until repetir<>'s';//fin until repetir calculos

  writeln(repetir);//para comprobar la variable repetir
end. :-)


24-Oct-2010 16:12
Antonio P.G.

Hola.

Efectivamente, es lo que me temía. La instrucción "read (opcion);" no introduce nada al programa. Sólo se "envían" los datos a éste cuando se trata de un "readln". (Tal vez me equivoque. En ese caso, profesor Nacho, por favor corrígeme).

La cosa es que si escribes "readln (opcion);", funcionará. Al menos conmigo ha sido así.

¡Adiós!


26-Oct-2010 19:53
Nacho Cabanes (+83)

Efectivamente, como ya anticipaba Antonio, la orden "read" es poco útil cuando se usa desde teclado. Permite introducir varios datos separados por espacios, pero eso es algo que puede llegar a ser útil cuando se trabaja a partir de un fichero, no tanto cuando un usuario introduce datos.

Por eso, en un programa "normal", en el que el usuario tenga que teclear los datos y pulsar Intro, deberías usar ReadLn.


27-Oct-2010 11:41
Fulanito de Tal

Muchas gracias a los dos. La verdad es que me habeis dejado de piedra. Así que el problema estaba en la entrada de "opcion", no en "repetir". Es que esa parte del programa funcionaba perfectamente, por eso me despisté. Si introducías una opción del menú incorrecta (por ejemplo 7) volvía a hacer la pregunta. Sin embargo el problema estaba ahí, no más adelante. Como se suele decir, nunca te acostarás sin saber una cosa más.






(No se puede continuar esta discusión porque tiene más de dos meses de antigüedad. Si tienes dudas parecidas, abre un nuevo hilo.)