[ Foro de Pascal ]
Cordial saludo y agradeciendo siempre su buena voluntad y ayuda.
Estoy realizando un programita pequeño sencillo de archivos de tipo, este es la parte del codigo donde tengo el problema:
program consulta;
uses crt;
type registro=record
referencia:integer;
descripcion:string;
saldo:real;
preciounitario:real;
end;
var archivo:file of registro;
dato:registro;
eleccion:char;
i:integer;
ref:integer;
encontrado,terminar:boolean;
procedure consultas;
begin
clrscr;
writeln;
writeln;
writeln;
writeln;
assign(archivo,'C:\inventar.txt');
reset(archivo);
writeln('consultas');
writeln;writeln;
writeln('cual es la referencia que desea consultar ');
encontrado:=false;
read(ref);
while (not eof(archivo)) do
begin
read(archivo,dato);
if dato.referencia=ref then
begin
writeln('referencia ',dato.referencia);
writeln('descripcion ',dato.descripcion);
writeln('saldo ',dato.saldo:4:2);
writeln('v/r unitario ',dato.preciounitario:2:2);
writeln;writeln;
write('presione una tecla para continuar ');
readkey;
encontrado:=true;
end;
end;
close(archivo);
end;
bien en 'C:\inventar.txt' tengo:
111 neveras 10 2000000
112 tv 8 1000000
113 pc 5 1500000
la compilacion la realiza correctamente, y al ejecutar me pide:
cual es la referencia que desea consultar: yo le digito 111 que es la referencia inicial que tengo en el archivo inventar.txt, que les mostre anteriormente, pero el sistema me envia el siguiente mensaje de error:
ERROR 100:DISK READ ERROR y la verda no entiendo a que puede ser debido ? y me lo marca en la linea del codigo que les anexe:
while (not eof(archivo)) do
begin
read(archivo,dato);// aqui me muestra como linea de error
agradeceria muchisimo me explicaran el porque o que puedo hacer? mil gracias
Saludos.
Lo que ocurre es lo siguiente:
Estás intentando leer records de un archivo de texto. El enunciado de tu pregunta de hecho lo indica "archivos con tipo".
Cuando haces archivos con tipo, lo primero es que la extensión es ".dat". El archivo no lo puedes crear desde el bloc de notas, sino que lo mejor es construirse un programa que que te los cree.
Tu programa lee registros, pues haz uno que los escriba. Es fácil, seguro que puedes. Incluso puedes añadirlo como una opción a tu programa, en plan "¿Quiere leer o escribir?".
Por cierto, un detalle del código que publicas: si te das cuenta, tras encontrar el ítem en la lista, el programa sigue recorriendo el archivo. Usa la variable "encontrado" en el while, y será más eficiente.
Si dudas, ya sabes.
¡Ciao!
Gracias antonio.
Una cosita es que me indicas que use la variable encontrado en el while,y bueno mirando el codigo yo la hago igual a true cuando encuentra el item, esta dentro del if que es cuando pregunto si lo encontro, tu mesugieres por fuera del if? es que ahi me confundi un poco pues el if esta dentro del while, por que seria mas eficiente? gracias
Buenos días.
A ver, la variable "encontrado" es de tipo boolean, es decir, puede verse como un interruptor que encendemos cuando hemos encontrado el ítem.
En el programa que envías, la condición de parada (así se llama) del bucle es "que se acabe el archivo". Por ello, "mientras no se acaba el archivo, leo". Ahora bien, ¿me interesa seguir leyendo si ya he encontrado el ítem? Sabemos que la respuesta es no, por lo que hay que salirse del bucle.
Entonces llegamos a la conclusión de que nuestra sentencia ha de ser algo como "Entrar en bucle mientras no se acaba el archivo Y no se encuentra el ítem". Creo que así está claro. Cuida esos paréntesis para que funcione.
¡Ciao!
Buenas tardes.
Antonio mil gracias por tu ayuda logre solucionar el programa tal y como me lo indicabas y me ejecuto correctamente muchas gracias por tu atencion y ayuda.
tengo este programa pero aun no me funciona dime en que puedo estar fallando o si lo estoy enfocando inadecuadamente, agradeciendo como siempre de antemano tu generosa ayuda:
se tiene un vector de enteros cualesquiera.Obtener otro de forma que el contenido de cada elemento del nuevo vector sea un indice que nos indique de menor a mayor los valores del array de enteros.
ejemplo:
vector_valores:
1 2 3 4 5 //indices del vector
10 5 -7 0 12 //valores del vector
vector indices:
1 2 3 4 5 //indices del vector
3 4 2 1 5 //valores del vector
Nota: El vector valores no se podrá modificar ni se puede hacer una copia del mismo
Bien hago lo siguiente pero el resultado no es el que espero …por favor ayudme en ello.
program vectorindices;
uses crt;
var i,j,posmenor:integer;
valores:array[1..5] of integer;
indices:array[1..5] of integer;
begin
clrscr;
writeln;
for i:=1 to 5 do
begin
write('entre el termino ',i, ' del vector: ');
readln(valores[i]);
end;
write('el vector original es:');
writeln;
for i:=1 to 5 do
write(valores[i]:4);
for i:=1 to 5 do
begin
posmenor:=i;
for j:=i+1 to 5 do
begin
if valores[j] < valores[i] then
posmenor:=j;
end;
indices[i]:=posmenor;
end;
writeln;
write('el nuevo vector indices es: ');
writeln;
writeln;
for i:=1 to 5 do
write(indices[i]:4);
readkey;
end.
El resultado que obtengo par el vector índices es:
4 4 3 4 5 que no es lo esperado
Saludos.
Bueno, he comprobado a mano el algoritmo principal de tu programa y no funciona, efectivamente.
Dicho algoritmo (el de los bucles anidados), indica la posición del último número más pequeño que el de una posición "i" dada, sin tener en cuenta las posiciones anteriores a la "i".
Es decir, la salida ha sido "4 4 3 4 5", que significa:
- El último número más pequeño que el de la posición 1 desde la posición 1 es el de la posición 4 (el cero).
- El último número más pequeño que el de la posición 2 desde la posición 2 es el de la posición 4 (el cero).
- El último número más pequeño que el de la posición 3 desde la posición 3 es el de la posición 3 (el -7).
- El último número más pequeño que el de la posición 4 desde la posición 4 es el de la posición 4 (el cero).
- El último número más pequeño que el de la posición 5 desde la posición 5 es el de la posición 5 (el 12).
Algunos detalles con respecto al algoritmo del código:
- Sólo compara los números que están por encima de una posición "i".
- Siempre compara con el número de la posición "i", no con "el más pequeño encontrado hasta ahora".
Te invito a que realices a mano lo que tu quieras hacer, es decir, CÓMO quieres que el PC te lo haga. Luego, buscas en tus movimientos patrones de repetición ("por aquí ya he pasado pero con uno menos...") y verás como seguro que te queda bien, o casi. Digo "casi" porque luego, con retocar un poco los índices sale.
Lo cierto es que a mí se me ocurren dos formas de resolverlo. Una implica la pérdida de los datos del vector durante el proceso, pero no incrementa el número de variables. La otra opción es añadiendo una variable de tipo vector de booleanos.
Te explico la segunda:
- En ésta, a parte de los vectores que ya tienes, añades el de booleanos, cuya longitud será, obviamente, igual a las de los otros.
- Se trata de buscar el mínimo del vector (eso es un problema básico, como el del máximo), y tras esto, modificar el valor booleano de la correspondiente casilla (por ejemplo a TRUE) y de apuntar el número de vuelta en esa posición, pero del otro vector.
- Ejemplo con tu vector, tras una primera vuelta, antes de empezar la segunda:
--> Vector original: 10 5 -7 0 12
--> Vector índices: - - 1 - -
--> Vector booleans: False False True False False.
-Por último, es que en la siguiente vuelta hacemos lo mismo (buscar el mínimo) pero sólo SI (if) es false el valor de las casillas.
La primera forma es un poco más chapuzas (a mi gusto). Ésta la podemos usar si los datos de entrada nos importan un pepino. Vaya, ahora que me doy cuenta, sí que hay que añadir una variable... aunque ésta será integer:
- Primero buscamos el máximo del vector, y lo guardamos en la variable "mx", por ejemplo.
- Le sumamos 1 a "mx", de forma que ya es mayor que el máximo.
- Ahora, hacemos como en el anterior algoritmo que he explicado, pero en vez de anotar en un vector de booleanos, damos el valor "mx" a la casilla que acabamos de declarar como la menor.
- Ejemplo con tu vector, tras una primera vuelta, antes de empezar la segunda:
NOTA: mx = 12 + 1; mx = 13.
--> Vector original: 10 5 13 0 12
--> Vector índices: - - 1 - -
- NOTA: este algoritmo no funciona si el máximo del vector es MaxInt, que es el mayor integer, debido al desbordamiento.
¿Entendido? Pues eso es todo. Por cierto, una "confesión personal": nunca he hecho un programa que involucre arrays sin lápiz y papel (y he hecho unos cuantos).
Espero haber sido de ayuda.
¡Ciao!
Antes como siempre darte las gracias por tu ayuda y tu tiempo.
Mira la verdad entendi lo siguiente de tu explicacion la idea es crear un vector booleano el cual en resumidas cuentas me servira para buscar el minimo del resto de valores que queden una vez hallado un minimo y los indices de eso minimos van quedando como valor en el vector resultado( que seria indices[])lo que no alcanzo a entender ya en codigo es lo que mencionas referente a la siguiente pasada me explico a traves de codigo:
program vector_indices;
uses crt;
var i,j,posmenor,menor:integer;
valores:array[1..5] of integer;
indices:array[1..5] of integer;
vector_F_V:array[1..5] of boolean;
begin
clrscr;
writeln;
for i:=1 to 5 do
begin
write('entre el termino',i,'del vector:');
readln(valores[i]);
vector_F_V[i]:=false;
end;
//busco el minimo del vector inicial
menor:=valores[1];
for i:=2 to 5 do
if valores[i]<menor then
begin
menor:=valores[i];
posmenor:=i;
end;
writeln;
vector_F_V[posmenor]:=true; // esto daria finalizado como veis una vez finalizado el for i lo siguiente:
false false true false false
writeln;
redkey;
end.
que debo colocar antonio dentro de este codigo para hacer lo que tu me indicas que ahora busque el menor entre los valores del vector_F_V que estan en false ( que es lo que no entiendo cuando te refieres a la siguiente pasada, osea como hago para no tener en cuenta ya ese minimo( que esta en true) y trabajar con los restantes valores )????.
otra cosa cada vez que encuentre un minimo ( y por ende su posicion)agrego al vector indices cada nuevo minimo verdad? es decir:
porejemplo cuando tenia:
false false true false false
como vemos el menor esta en la tercera posicion que la almaceno porj en la variable posmenor asi entonces tendre en el vector indices algo asi:
indices[i]:=posmenor // es decir indices[1]:=3
en el siguiente caso que es donde no se como llegar tendria:
false false true true false ( es decir ya encontre el 2do menor del vector original, indices[2]:=4 pues posmenor es el indice 4 que correponde al valor 0 del vector valores)) ,asi que el vector indices valdria en este momento:
3 4 _ _ _ verdad y asi sucesivamente verdad amntonio o estoy errado ayudame porfa...
mil gracias por tu generosidad
Hola.
Primero, perdona porque creo que no había entendido el problema del todo bien, pero ahora sí.
A ver, todo lo que tienes es correcto, excepto por unos detalles. El primero referente a lo de "saber si tengo que usar el número o no, mediante el vector de booleans".
Pues aquí hay que añadir una condición. Fíjate que tú coges y cambias el valor de la variable "menor" si es más pequeño el número. Pues añade ahí la condición referente a la posición boolean, "y si la casilla del vector de booleans es...". Ahí te lo dejo.
Respecto al segundo detalle: Se trata de un bucle anidado, es decir, has hecho un bucle, para comparar números y así hallar la primera respuesta, pero necesitas hallar las otras 4.
De hecho, te diré algo más. Me acabo de dar cuenta de que tienes que hacer otro sub-bucle más, para elegir el primer mínimo, con el que empiezas a comparar. Es decir, el esquema es el siguiente.
........................
..bucle principal con "i"
....bucle secundario con "j" para coger un primer mínimo de referencia
....bucle secundario que ya tienes hecho (más o menos), con "j" u otra variable que quieras
¿Por qué eso del bucle secundario para el mínimo? Pues porque imagina lo que ocurriría si tomamos como base uno que ya estaba en true. Por eso, tenemos que coger como "primer mínimo" para la variable "menor" el primero que encontremos en false.
En fin amigo, lápiz y papel. Espero que te haya servido.
Ciao.
Mil gracias Antonio y Nacho C. por su ayuda y su tiempo, he podido solucionar el problema gracias a sus aportaciones valiosas y que agradezco muchisimo.
(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.)