идея задачи в том: что бы произвести со списком различные действия. Проблема в удалении элемента списка по имени. Пробовал различные условия и составление процедуры/ процедур, но что бы полноценно из любого места удалял эл-т не выходит. Как пр: "если ввожу 3 эл-та и удаляю последний - все хорошо. но если следом удаляю 2 то он впринцепи прогоняет и выводит ответ: но вмете с тем и вылетает." . Косяк, я предполагаю, в неккоректных условиях, т.е. выходит за пределы списка.
опишите подробней пожалуйста мои ошибки.
P.S.
остальные условия работают хорошо, но если заметите недочеты , укажите их, пожалуйста.
Прикрепленные файлы
_______________________.rar ( 33.18 килобайт )
Кол-во скачиваний: 185
if (p^.mName=dName) then
begin
writeln;
writeln('данные найдены в картотеке.Удаляем');
Q:=p;
p:=Q^.mNext; // <--- Угу...
Q^.mNext:=p^.mNext;
p^.mNext:=nil;
dispose(p);
writeln;
writeln('информация о ',dName ,' удалена');
end
procedure delete_person (var L: PPerson);
var
p, Q : PPerson;
dName: string;
begin
if Empty(L)= true then
writeln('извините, но список пуст')
else
begin
writeln('введите имя удаляемого клиента');
readln(dName);
LowCase(dName); // переводим введенное имя в нижний регистр
p := L;
while Assigned(p^.mNext) do
begin
if p^.mNext^.mName = dName then
begin
Q := p^.mNext;
p^.mNext := Q^.mNext;
dispose(Q);
writeln('информация о ',dName ,' удалена');
end
else
p := p^.mNext;
end;
end;
end;
вот молотый компот. Как просто-то. Спасибо. очень простая и понятная реализация.
еще вопрос. как мне написать корректный ввод номера телефона ? для имени я сделал: вроде хорошо. В плане рациональности не уверен правда.
я думаю что бы перевести mPhone в string и тогда функция CheckPhone будет аналогична CheckName . В этом случае смогу так же вводить с пробелами (" пр: 12 34 456 " ). Или суш. скрытый от меня более рацио-ый вар-т проверки корректного ввода без глобальных изменений во всей программе ?
P.S. недочеты я поправил почти все, осталось очистку списка сделать, но это не сложно.
Прикрепленные файлы
2________________________.rar ( 33.3 килобайт )
Кол-во скачиваний: 194
{--заполнение списка--}прекрасно с этим справляется. Программа будет запрашивать ввод до тех пор, пока то, что пользователь введет не будет правильным целым числом. Можно там же, скажем, запретить отрицательные числа:
procedure fill_spisok (var p: PPErson);
var
s, aName : string; aPhone : integer;
i, v : integer;
isOk : boolean;
begin
writeln('сколько персон собираетесь вписать?');
readln(v);
for i:=1 to v do
begin
writeln;
writeln('write a phone');
repeat
readln(s);
// Эта функция описана в SysUtils, подключи ее после Implementation
isOk := TryStrToInt(s, aPhone);
if not isOk then
writeln('Неправильно введен номер. Попробуйте еще раз');
until isOk;
writeln('write a name');
repeat
readln(aName);
LowCase(aName);
isOk := CheckName(aName)
if not isOk then
writeln('неправильно введено имя. Повторите ввод');
until isOk; // Зачем было функцию вызывать дважды?
writeln;
create_spisok(p, aName, aPhone);
end;
end;
isOk := TryStrToInt(s, aPhone) and (aPhone > 0);, или числа с маленьким количеством цифр (подумай сам как это сделать)...
function CheckName(var s: string): boolean;выглядит привычнее, и не будет идти по строке до упора, как только "поймает" первый неподходящий символ - тут же вернет "ложь"...
var
i : integer;
begin
result := false;
for i := 1 to Length(s) do
if not (s[i] in ['a' .. 'z']) then exit;
result: = true;
end;
указатель на элемент списка?
если я хочу попросить "что лежит под 3 номером, и он вывести должен имя и телефон данного служащего" .
т.е. мне по сути надо пронумеровать элементы списка?
задать счетчик после каждого нового добавления или в ТPerson завести этот счетчик ?
----
Прикрепленные файлы
2________________________.rar ( 43.86 килобайт )
Кол-во скачиваний: 175
function search(const L : PPerson; s : Tname) : PPerson; // Возвращается что? Указатель..., а теперь, вместо того, чтобы "растворять" поиск в программе и размазывать его по нескольким местам, просто...
var p : PPerson;
begin
s := LowerCase(s); // переводим введенное имя в нижний регистр
s := AnsiLowerCase(s);
search := nil; // на случай, если ничего не найдется...
p := L;
while p^.mNext <> nil do
begin
if p^.mNext^.mName = s then
begin
search := p; exit;
end
else p := p^.mNext;
end;
end;
case n of
1:
begin
writeln('введите имя');
readln(dName);
p := search (L, dName); // <--- !!!
if Assigned (p) then
begin
Q := p^.mNext;
p^.mNext := Q^.mNext;
dispose(Q);
writeln;
writeln('информация о ',dName ,' удалена');
end
else
begin
writeln ('данный служащий не найден в списке');
delete_person(L); // Вот этого бы я не делал. Рекурсии здесь на фиг не надо.
end;
end;
writeln('напишите имя нужного вам человека');Структура программы упростится.
readln(fName);
p := search (L, fName);
if Assigned (p) then
begin
// действия при нахождении фамилии в списке
end
else // действия, когда фамилия не найдена
case n of
1: begin
writeln; // <--- Вот именно тут должна вводиться фамилия для удаления
delete_person(a);
// А тут - должен обрабатываться результат.
// Сама delete_person НИЧЕГО не должна печатать и запрашивать у пользователя
end;
writeln ('воздух сортировать что ли ?')к сортировке списка? bubble_sort получила несортированный список, после ее выполнения список стал упорядоченным. Всё! Никакой самодеятельности больше. Все остальное к логике не относится. Это - интерфейс пользователя. Хочется похохмить - верни из bubble_sort единицу при пустом списке и 2-ку при списке, состоящем из одного элемента, и сделай:
case bubble_sort(L) ofтам же, в Interface_1.
1 : writeln ('воздух сортировать что ли ?');
2 : writeln ('не будем мусолить одного служащего');
end;
спасибо большое за помощь