Версия для печати темы
Нажмите сюда для просмотра этой темы в оригинальном формате
Форум программистов > Delphi: Для новичков > Нужна помощ с процедурой


Автор: BTCY 23.6.2008, 15:52
Здравствуйте.
ОЧЕНЬ Нужна помощ. Такая задача, написать ПРОЦЕДУРУ которая у строки удаляет все пробелы в начале строки и в конце.
PS Прошу ещё разъяснить ваши действия.



Автор: VanHelsing 23.6.2008, 15:58
Считываете строку, и посимвольно (с начала и с конца строки) проверяете является символ пробелом или нет. Запоминаете позицию где символ не равен пробелу и выделяет в эту строку.

Автор: BTCY 23.6.2008, 16:01
Цитата(VanHelsing @ 23.6.2008,  15:58)
Считываете строку, и посимвольно (с начала и с конца строки) проверяете является символ пробелом или нет. Запоминаете позицию где символ не равен пробелу и выделяет в эту строку.

Плиз,можеш это на примере кода всё мне разжевать? Так лучше разберусь.

Автор: Rrader 23.6.2008, 16:05
Посмотри, как в VCL сделаны функции TrimLeft И TrimRight

Автор: morpheyushka 23.6.2008, 16:20
Что бы удалить пробелы сначала и сконца строки одновременно просто Trim
Код

var
 s: String
...
 s := '             Строка с пробелами вначале и вконце!               ';
 s := Trim(s); // s = 'Строка с пробелами вначале и вконце!'
 


и всё smile 


Не забудь закрыть тему!

Автор: BTCY 23.6.2008, 16:32
Цитата(morpheyushka @ 23.6.2008,  16:20)
Что бы удалить пробелы сначала и сконца строки одновременно просто Trim
Код

var
 s: String
...
 s := '             Строка с пробелами вначале и вконце!               ';
 s := Trim(s); // s = 'Строка с пробелами вначале и вконце!'
 


и всё smile 


Не забудь закрыть тему!

Мне TRIM нельзя использовать =(

Автор: Rrader 23.6.2008, 16:32
morpheyushka, если есть пробелы в середине, то и они удалятся. Я думаю, автору не нужно это smile 
BTCY, скажи, как тебе надо? Только по краям или все? smile 

Автор: morpheyushka 23.6.2008, 16:34
Цитата(Rrader @  23.6.2008,  16:32 Найти цитируемый пост)
morpheyushka, если есть пробелы в середине, то и они удалятся. Я думаю, автору не нужно это smile 



Нет, не удалятся...проверено на 100% smile 
только вконце и вначале

Добавлено через 3 минуты и 55 секунд
Цитата(BTCY @  23.6.2008,  16:32 Найти цитируемый пост)
Мне TRIM нельзя использовать =( 



Тебе нужно самому эту процедуру реализовать или я что-то не понял?

Автор: Rrader 23.6.2008, 16:39
Мой глюк, извиняюсь smile 

Автор: BTCY 23.6.2008, 16:39
Цитата(Rrader @ 23.6.2008,  16:32)
morpheyushka, если есть пробелы в середине, то и они удалятся. Я думаю, автору не нужно это smile 
BTCY, скажи, как тебе надо? Только по краям или все? smile

Да,мне нужно толька по краям. 
Чесно говоря я сам не понял что отменя требуют, я процитировал в первом посте как препод мне сформулировал задачу.  Но вроде он говорил трим не использовать. 

Автор: morpheyushka 23.6.2008, 16:43
Значит он дал тебе задание - что бы ты сам это реализовал))

Автор: BTCY 23.6.2008, 16:50
Цитата(morpheyushka @ 23.6.2008,  16:43)
Значит он дал тебе задание - что бы ты сам это реализовал))

Каким способом? я непонимаю =(  smile  , может поможете? 

Автор: ama_kid 23.6.2008, 17:15
Цитата(BTCY @  23.6.2008,  16:50 Найти цитируемый пост)
Каким способом?
Навскидку:
Код
function TrimOwn(const Param:string):string;
var
 p:integer;
 tmp_str:string;
 i:integer;
begin
 Result:='';
 tmp_str:='';
 p:=1;
 while Param[p]=' ' do inc(p);
 for i:=length(Param) downto p do tmp_str:=tmp_str+Param[i];
 p:=1;
 while tmp_str[p]=' ' do inc(p);
 for i:=length(tmp_str) downto p do Result:=Result+tmp_str[i];
end;
Оптимизируй сам  smile 

Автор: BTCY 23.6.2008, 17:25
Цитата(ama_kid @ 23.6.2008,  17:15)
Цитата(BTCY @  23.6.2008,  16:50 Найти цитируемый пост)
Каким способом?
Навскидку:
Код
function TrimOwn(const Param:string):string;
var
 p:integer;
 tmp_str:string;
 i:integer;
begin
 Result:='';
 tmp_str:='';
 p:=1;
 while Param[p]=' ' do inc(p);
 for i:=length(Param) downto p do tmp_str:=tmp_str+Param[i];
 p:=1;
 while tmp_str[p]=' ' do inc(p);
 for i:=length(tmp_str) downto p do Result:=Result+tmp_str[i];
end;
Оптимизируй сам  smile

Спасибо. Это процедура? Или всётаки функция?

Добавлено через 3 минуты и 8 секунд
Кто нибуть как нибуть может показать как сделаны функции TrimLeft И TrimRight ? А то что-то я у себя их в VCL не нахожу o_O

Автор: morpheyushka 23.6.2008, 17:40
Цитата(BTCY @  23.6.2008,  17:25 Найти цитируемый пост)
Кто нибуть как нибуть может показать как сделаны функции TrimLeft И TrimRight ? А то что-то я у себя их в VCL не нахожу o_O 



тебе же уважаемый ama_kid дал исходник функции...одна ее половина (первая) делает TrimLeft, а вторая - последняя - TrimRight. Просто нужно обратно будет развернуть строку

Автор: BTCY 23.6.2008, 17:54
Цитата(morpheyushka @ 23.6.2008,  17:40)
Цитата(BTCY @  23.6.2008,  17:25 Найти цитируемый пост)
Кто нибуть как нибуть может показать как сделаны функции TrimLeft И TrimRight ? А то что-то я у себя их в VCL не нахожу o_O 



тебе же уважаемый ama_kid дал исходник функции...одна ее половина (первая) делает TrimLeft, а вторая - последняя - TrimRight. Просто нужно обратно будет развернуть строку

Можете расписать там по строчкам мне объяснения? Мне не только принести код надо будет,но и объяснить его =( За одно может строки развернете про которые говорили? а то я вообще не понимаю)

Автор: ama_kid 23.6.2008, 19:01
Цитата(BTCY @  23.6.2008,  17:25 Найти цитируемый пост)
Это процедура? Или всётаки функция?
В данном случае - это функция. Если тебе надо именно процедурой (а ты понимаешь разницу между этими понятиями?) - тогда просто заголовок немного переделать надо...
Цитата(BTCY @  23.6.2008,  17:54 Найти цитируемый пост)
За одно может строки развернете про которые говорили?
Разворачивать вроде ничего не надо smile
Цитата(BTCY @  23.6.2008,  17:54 Найти цитируемый пост)
Можете расписать там по строчкам мне объяснения?
Код
function TrimOwn(const Param:string):string; // Объявление функции. 
var   // Объявление локальных переменных
 p:integer; // Временная переменная для хранения позиции первого непробельного символа
 tmp_str:string;  //временная строчная переменная
 i:integer;  // локальная переменная цикла
begin   // начало тела функции
 Result:='';   //Result - это переменая, которая хранит возвращаемое функцией значение. Инициализируем её
 tmp_str:='';  // инициализируем временную переменную
 p:=1;  // аналогично
 while Param[p]=' ' do inc(p);  // пока встречаются пробелы - увеличиваем счетчик
 for i:=length(Param) downto p do tmp_str:=tmp_str+Param[i]; // от последнего символа до первого 
                     //непробельного символа копируем во временный результат
                     //получаем инвертированную строку с отсеченными первыми пробелами
 p:=1;  // еще раз инициализируем 
 while tmp_str[p]=' ' do inc(p); // делаем второй раз увеличение счетчика пробелов
 for i:=length(tmp_str) downto p do Result:=Result+tmp_str[i]; // от последнего символа до первого 
                     // непробельного символа копируем в результат
                     // в итоге строка опять перевернется и исходные завершающие пробелы отсекутся...
end; // окончание тела функции

Цитата(BTCY @  23.6.2008,  17:25 Найти цитируемый пост)
а то я вообще не понимаю
Разбирайся и спрашивай...  smile 

Автор: BTCY 23.6.2008, 20:04
Мега спасибо!!! smile  smile 
Мне нужна процедура. Что там вверху заменить и на что?


Автор: ama_kid 23.6.2008, 20:31
Цитата(BTCY @  23.6.2008,  20:04 Найти цитируемый пост)
Мне нужна процедура. Что там вверху заменить и на что?
примерно так:
Код
procedure TrimOwn(const Param:string; var Result: string); // Объявление процедуры


Автор: Beltar 24.6.2008, 07:18
Код

procedure MyTrim(var S:String);
var S1:String;
    i,L:Integer;
begin
i:=1;
L:=Length(S);
S1:='';
while ((i<=L) and (S[i]=' ')) do inc(i);
while ((i<=L) and (S[i]<>' ')) do
  begin
  S1:=S1+S[i];
  inc(i);
  end;
S:=S1;
end;


Вот еще простейший вариант, чуть менее громоздкий, всего 2 цикла и все-таки
Код

procedure TrimOwn(const Param:string; var Result: string);


для меня выглядит немного странно, преподы дают, конечно, глупости, но если уж мутить процедуру, то пусть уж она изменяет переменную.
Однако при использовании этого простейшего варианта убедись, что включена короткая схема вычисления лог. выражений, иначе можешь AV схлопотать. smile


PS А вместо var Result логичнее out Result указать, но это уже тонкости, которые студенту не нужны. smile

Автор: ama_kid 24.6.2008, 07:28
Цитата(Beltar @  24.6.2008,  07:18 Найти цитируемый пост)
Вот еще простейший вариант
Код
while ((i<=L) and (S[i]<>' ')) do
  begin
  S1:=S1+S[i];
  inc(i);
  end;
Вроде как будет работать только до первого пробела в середине строки. Этот цикл надо организовать от конца строки в сторону уменьшения...
Цитата(Beltar @  24.6.2008,  07:18 Найти цитируемый пост)
Однако при использовании этого простейшего варианта убедись, что включена короткая схема вычисления лог. выражений, иначе можешь AV схлопотать
Я конечно дал такое объявление функции навскидку (чтобы не изменять тело процедуры, у меня нет сейчас дельфи под рукой), но поясни плз данный тезис, я что-то его не догнал. В каком месте там может быть AV?

Автор: Beltar 24.6.2008, 08:42
Цитата

Вроде как будет работать только до первого пробела в середине строки. Этот цикл надо организовать от конца строки в сторону уменьшения...


Признаю свою неправоту. Оптимизировать не получилось, абыдна.

Цитата

о поясни плз данный тезис, я что-то его не догнал. В каком месте там может быть AV?



Код

(i<=L) and (S[i]<>' ')

Когда i станет больше длины, S[i] будет выходом за границу строки.
В твоем варианте я проблем не вижу.

Автор: ama_kid 24.6.2008, 08:58
Цитата(Beltar @  24.6.2008,  08:42 Найти цитируемый пост)
Когда i станет больше длины, S[i] будет выходом за границу строки
Когда i станет больше длины строки - сработает условие (i<=L) и до условия (S[i]<>' ') не дойдет, так что "выхода" быть не должно.

Добавлено через 1 минуту и 52 секунды
Цитата(Beltar @  24.6.2008,  08:42 Найти цитируемый пост)
Оптимизировать не получилось, абыдна.
Оптимизировать там можно раза в два по объему кода, но пусть топиккастер сам попробует подумать на эту тему smile

Автор: morpheyushka 24.6.2008, 09:16
по моему тему уже можно закрывать...лучше бы это сделал модератор, а то от хозяина темы не дождёшься smile 

Автор: Beltar 24.6.2008, 09:22
Цитата

Когда i станет больше длины строки - сработает условие (i<=L) и до условия (S[i]<>' ') не дойдет, так что "выхода" быть не должно.


Именно. Это и называется вычислением по короткой схеме, но в опциях проекта в разделе Compiler можно включить полное вычисление.
Конечно, я знаю, что там стоит по умолчанию, но думал пусть топикстартер попугается. Вопросов позадает. Впрочем бояться ему оказывается нечего, :( я забыл, что в конце строки еще нолик есть и S[Length(S)+1] как раз на него и покажет.

Автор: BTCY 24.6.2008, 14:15
Всем БОЛЬШОЕ спасибо кто принимал участие в дискуссии!!! Отдельное МЕГА спасибо ama_kid !
Сдал на 5 эту задачу.  smile 

Powered by Invision Power Board (http://www.invisionboard.com)
© Invision Power Services (http://www.invisionpower.com)