Hola.
Al estar trabajando ahora en modo consola de texto, las posibilidades para controlar el formato de entrada son algo limitadas.
Y yo tampoco soy ningún experto en Pascal, de hecho, estoy aprendiendo de nuevo a medida que me vas preguntando cosas je je...
Una forma que se me ocurre para por ejemplo evitar que se ingrese una cédula con caracteres no admitidos (letras, símbolos, etc...) es crear una función booleana.
No se si ya has trabajado con
procedimientos y
funciones.
Una
función es un pequeño código que se escribe a parte del programa principal que se va a dedicar a una tarea muy concreta.
Recibe un dato (o varios, según necesitemos), hace los cómputos que le pidamos y al final devuelve un valor: un integer, un real, un string,...
En nuestro caso nos puede interesar que devuelva un boolean, es decir, que devuelva true o false.
Lo que vamos a querer es que la función reciba la cédula que ha tecleado el usuario, que compruebe carácter a carácter si se trata de una cifra numérica o no.
Si solo encuentra números, el resultado a devolver será true, es decir, la cédula es correcta.
En cambio, si encuentra algún carácter que no es un número, entonces devolverá false. La cédula no es correcta.
Así, en nuestro programa principal podemos hacer que la petición de la cédula al usuario esté dentro de un bucle que se repita una y otra vez hasta que nuestra función devuelva valor true porque considere que la cédula es válida.
Esta podría ser la función que necesitamos:
{Declaramos una funcion para validar la cedula}
function validarCedula(cedula:string):boolean;
var
valorAscii: integer;
begin
validarCedula := true;{Si se encuentra un caracter que no es numero, pasara a ser false}
for i:= 1 to length(cedula) do
begin
valorAscii := ord(cedula[i]);
if (valorAscii < 48) or (valorAscii > 57) then
validarCedula := false;
end;
if not validarCedula then
begin
writeln('La cedula solo puede contener numeros');
writeln('Intente de nuevo...');
writeln();
end;
end;
Te explico un poco lo que significa cada línea:
function validarCedula(cedula:string):boolean;Esta es la "firma" o declaración de nuestra función.
- Se va a llamar
validarCedula.
- Entre paréntesis le indicamos que dato/s va a recibir cuando se la invoque dentro del programa principal.
En este caso le estamos diciendo que va a recibir un dato string y que dentro de la función se va a llamar
cedula. Ojo, este nombre del dato no tiene porque coincidir con el nombre que tendrá en el programa principal, pueden ser nombres distintos. Aquí simplemente le estamos diciendo que nombre queremos que tenga ese dato string dentro
de la función.
- Al final de la firma le estamos diciendo que tipo de dato queremos devolver, en este caso un boolean(verdadero/falso).
var
valorAscii: integer;Dentro de la función, podemos hacer otra declaración de variables si lo necesitamos. Es opcional.
Declaramos un integer llamado
valorAscii¿Por qué ese nombre? Porque como veremos a continuación, esta función lo que va a hacer es obtener el código ASCII de cada carácter del string cedula y comprobar si pertenece a un carácter entre 0 y 9, que son los únicos que vamos a considerar aceptables.
Después, comienza el código de la función:
begin
validarCedula := true;{Si se encuentra un caracter que no es numero, pasara a ser false}Lo primero que hacemos es asignar el valor true a la función. En Pascal la función es al mismo tiempo una variable, por eso podemos asignarle un valor de este modo.
Así que en realidad, en Pascal, la función no
retorna un valor, si no que lo
adopta.En otros lenguajes como C y derivados (C++, Java, C#...) esto no es así en absoluto, las funciones no adoptan valores, si no que los retornan.
Esto lo comento como curiosidad.
Volviendo a esa línea, ¿por qué comenzamos dándole valor true si aún el programa no ha comprobado ningún carácter?
Porque para simplificar el código, vamos a comenzar considerando que la cédula es correcta. Luego, si el código encuentra algún carácter
no aceptable, cambiará el valor de la función a false.
for i:= 1 to length(cedula) do
begin
valorAscii := ord(cedula[ i ]);
if (valorAscii < 48) or (valorAscii > 57) then
validarCedula := false;
end;Comienza un bucle que va desde 1 hasta la longitud que tenga el string cédula. De este modo usaremos este indice para visitar cada uno de los caracteres que tiene el string, igual que si fuera un array. De hecho, un string es un array de caracteres.
Lo primero que hace es invocar a la función ord(), que pertenece a Pascal, que lo que hace es recibir un caracter del string cedula y devolvernos su valor ASCII, que lo recogemos en el integer que habíamos declarado previamente.
Luego preguntamos si este valor ASCII
es inferior a 48 ó superior a 57. ¿Por qué?
Si le hechas un vistazo a
la tabla ASCII verás que los caracteres del 0 al 9 están asignados a los códigos entre 48 y 57.
Entonces, si la función encuentra un carácter que está fuera de ese rango, significa que no es un número entre 0 y 9, por lo tanto la cédula contiene caracteres no válidos y es entonces cuando la función adopta valor false. Y mantendrá este valor aunque el bucle siga adelante y encuentre números válidos en los próximos caracteres.
Basta con que haya una sola letra o símbolo para que la cédula sea rechazada.
if not validarCedula then
begin
writeln('La cedula solo puede contener numeros');
writeln('Intente de nuevo...');
writeln();
end;Esta parte es simplemente para informar al usuario de que se ha equivocado con la cédula ingresada.
Estos mensajes solo aparecen cuando la función tiene valor false.
Preguntar
if not validarCedula es exactamente lo mismo que pregunta
if validarCedula = falseY este será el análisis de nuestra función, ahora vamos a ver como usarla en el programa principal.
begin
inc(cantidad);
WriteLn('Introduciendo al trabajador ', cantidad);
repeat
Write('Introduzca Cedula del trabajador: ');
ReadLn(tra[cantidad].cedula);
until validarCedula(tra[cantidad].cedula);{Hasta que la funcion devuelva true}
write('Introduzca el nombre del trabajador: ');
Como vemos, la petición de la cédula la hacemos dentro un bucle
repeat ... until, que se va a repetir hasta que la función
validarCedula() consiga tener valor true.
Esta es una forma de solucionar lo que pides, seguramente hay formas mejores, como usar
expresiones regularesPero ahora mismo no tengo ni idea de como se usan en Pascal y además requieren cierto aprendizaje y quizás no es momento ahora de que te adentres en ellas.
Te adjunto para descargar el archivo .pas para descargar, por si tienes dudas de donde he declarado la función.
En principio la función la puedes declarar en cualquier sitio fuera del cuerpo principal.
Pero fíjate que en este caso, en la función utilizo la variable i para el bucle for que está en la declaración
var principal.
Entonces, conviene que la función esté declarada después del
var principal porque si no, no sabrá qué es la variable i al compilar.
Ahora que lo pienso, la verdad es que habría sido más correcto declarar dentro de la función, otro integer distinto para su bucle for.
Al usar la variable i que se ha declarado en el
var principal ponemos en riesgo el buen funcionamiento del programa.
En este caso no pasa nada, pero imagina que dentro de un bucle for que está usando esa variable i como indice, invocamos a nuestra función que también va a usar esa misma variable como indice.
La función estaría alterando los valores de i y el bucle for no estaría completando correctamente sus iteraciones.
Así que mejor que la función use sus propias variables internas y no las declaradas para el programa principal para evitar estos problemas.
En fin, prueba estos cambios y pregunta si tienes dudas.
Un saludo.