Главная страница
Top.Mail.Ru    Яндекс.Метрика
Текущий архив: 2005.06.14;
Скачать: CL | DM;

Вниз

Посимвольно формировать String   Найти похожие ветки 

 
810   (2005-05-25 06:20) [0]

Пишу простейшую функцию. Берет из первой строки i-тый симовол и приклеивает в конец второй строки.
-----------------------------------------------
var
  s1:String;
  s2:String;
  i: integer;
begin
  s1:="eiouirwulerjkq.knci34t934urlj,mvmdjgf";
  s2:="";

  FOR i:=1 To length(s1) DO
    begin

     {здесь действия, не затрагивающие значения s1[i]}

     s2:=s2+s1[i];

    end

  result:=s2;

end;
-------------------------------------------------------

Проблема: s2 всегда пустая!!! Явно, что-то не так с типами.
Прошу ткнуть носом.


 
Skier ©   (2005-05-25 06:51) [1]

Этот код правильный...
А зачем именно в цикле копировать ?


> {здесь действия, не затрагивающие значения s1[i]}

Что-то не очень верится...


 
810   (2005-05-25 07:03) [2]

Этот код правильный...
---------------------------------------
Почему тогда s2 пустая?

А зачем именно в цикле копировать ?
> {здесь действия, не затрагивающие значения s1[i]}
Что-то не очень верится...
--------------------------------------------

Вообще-то функция замещает в символьной строке указанный символ другим указанным символом. Используется при конвертации символьных полей, содержащих значения денежных сумм типа "1235646.56"  При использовании StrToFloat() она ругается на точку. Приходится заменять.
В цикле иду от первого символа до последнего и если текущий символ = "." то меняю на ","


 
Antonn ©   (2005-05-25 07:10) [3]

а поробуй временно не s2:="" а s2:=" "


 
Antonn ©   (2005-05-25 07:18) [4]

хотя и так все работает...


 
810   (2005-05-25 07:31) [5]

Вот РЕАЛЬНЫЙ код (copy + paste):

-----------------------------------------------------------------
function StrTran(s, ss, sr: string): string;

{
s - исходная строка например "156.50"
ss - заменяЕМЫЙ символ например "."
sr - замещаЮЩИЙ символ например ","
}

var
   i: integer;
   r: string;
begin

 i:=0;
 r:=" ";

 For i:=0 To Length(s) do
   begin
     IF s[i]=ss Then r:=r+sr ELSE r:=r+s[i];
   end;

 result:=string(PChar(r));

 ShowMessage("Sum= "+r);

end;
-----------------------------------------------------------------
Вот этот ШоуМессадьж выдает мне пустую строку.
Инициализировать r пробелом пробовал - не помогает.


 
begin...end ©   (2005-05-25 07:40) [6]

> 810   (25.05.05 07:31) [5]

> For i:=0 To Length(s) do
>    begin
>      IF s[i]=ss Then r:=r+sr ELSE r:=r+s[i];
>    end;

Нумерация символов в длинной строке начинается с единицы. Вы на первом проходе обращаеттесь к символу S[0], там, вероятно, оказывается символ #0, он прибавляется к строке r и является её завершающим символом. Нужно изменить в заголовке цикла начальное значение счётчика на 1.

Но я бы сделал функцию примерно так:

function StrTran(const s: string; ss, sr: Char): string;
var
 I, L: Integer;
begin
 L := Length(s);
 SetLength(Result, L);
 for I := 1 to L do
   if s[I] = ss then
     Result[I] := sr
   else
     Result[I] := s[I]
end.


 
810   (2005-05-25 07:59) [7]

начальное значение счётчика на 1
------------------------------------------

Да, действительно, это помогло. Кто бы знал .......

Но я бы сделал функцию примерно так:
------------------------------------------
А почему именно так? У вас есть время объяснить начинающему?
Все дело в жестко фиксированных размерах?


 
MBo ©   (2005-05-25 08:00) [8]

см. в хелпе StringReplace


 
begin...end ©   (2005-05-25 08:10) [9]

> 810   (25.05.05 07:59) [7]

> А почему именно так?

1. Прибавление очередного символа к строке каждый раз приводит к перераспределению памяти под строку. Это замедляет весь процесс, и особенно заметно это будет для больших по величине строк. Поскольку здесь размер строки-результата заранее известен (он равен размеру исходной строки), лучше сразу установить нужную длину результирующей строки (т.е. сразу выделить необходимую память) и обращаться к её символам.

2. Строки, которые не изменяются внутри функции (в данном случае -- s), лучше передавать с модификатором const. Это позволит компилятору сгенерировать более компактный и быстрый код.

3. Поскольку речь в данном случае идёт о замене одиночного символа на другой одиночный символ, то ss и sr лучше сделать типа Char, а не string. Так будет правильнее и быстрее.


 
sniknik ©   (2005-05-25 08:40) [10]

> При использовании StrToFloat() она ругается на точку. Приходится заменять.
исправь первопричину и ничего замешать будет не нужно. DecimalSeparator:= "."; перед использованием и ругаться не будет. (в написании мог ошибится, если так иши в хелпе похожее)


 
evvcom ©   (2005-05-25 08:43) [11]


> При использовании StrToFloat() она ругается на точку.

есть function StrToFloat(const S: string; const FormatSettings: TFormatSettings): Extended; overload; и FormatSettings.DecimalSeparator. Это тоже не помогает?


 
810   (2005-05-25 17:25) [12]

Это тоже не помогает?
----------------------------------------------------------
Ну вот, начали пинать.....:-)))))) (шютка юмора)

Я ж начинающий. О нумерации стрингов с 1 не знал. Ибо самоучка.
Чтобы искать в хелпе, тоже надо знать, что ищешь. Кто ж мог предполагать, что есть DecimalSeparator..... Ведь если не знаешь как он называется - в хелпе фиг найдешь.

Лучше расскажу о задаче.
Задача очень маленькая. Программа по сути - насос из одной DBF в другую, но DBF эти - разных форматов. В источнике сумма содержится в поле CHARACTER с разделителем "." а в приемнике NUMERIC с разделителем ","
Здесь вмешиваться никуда нельзя и повлиять ни на что - тоже. То есть, в данной "задаче" это - секция "Дано:"

Поскольку все очень просто, и чтобы не нагружать программу излишними фичами (типа БДЕ) я использую фришный компонент TDbf вместо TTable.

При закачке записей делаю:

{Активирую нужный индекс в TDbf1
Устанавливаю указатель на первую запись
по некоторому условию}

WHILE [некоторое условие]
TDbf2.Append;
 
  TDbf2Summa.Value := StrTran(TRIM(TDbf1Sum.Value), "." , "," );
 
  {и другие поля с другими трансформациями (штук 15 полей)}

TDbf2.Post;

TDbf1.Next;

end;

Если я применю DecimalSeparator, то он (наверное) подействует глобально. Т.е. все равно придется заменять, тогда уже, точку на запятую при записи в TDbf2. В этом могу и ошибаться, ибо как я говорил - новичок (надо попробовать....)

Ну, и все. В таблицах никогда не будет более пары-тройки тыщ записей (это с запасом на будущее), ибо в конце дня они принудительно очищаются и пакуются..... "Тормозов" не замечено,
хотя результирующая таблица висит в сетке и будут работать с ней ежедневно и одновременно не более 20 юзеров.

Спасибо всем, кто просвящал меня, "темного"


 
sniknik ©   (2005-05-25 18:15) [13]

> Если я применю DecimalSeparator, то он (наверное) подействует глобально.
правильно. но можно обойти, прочитай внимательнее [11].

> Т.е. все равно придется заменять, тогда уже, точку на запятую при записи в TDbf2
неверно. достаточно заменить на чтото одно. в данном случае на точку т.к.
> В источнике сумма содержится в поле CHARACTER с разделителем "." а в приемнике NUMERIC с разделителем ","
так примерно, если конечно этот TDbf аналогичен стандартным компонентам по методам (AsFloat/AsString).
DecimalSeparator:= "."
WHILE [некоторое условие]
 TDbf2.Append;

 TDbf2Summa.AsFloat:= StrToFloat(TDbf1Sum.AsString);

 {и другие поля с другими трансформациями (штук 15 полей)}

 TDbf1.Next;
end;
if (TDbf2.State = dsEdit) or (TDbf2.State = dsInsert) then TDbf2.Post; {на случай пустой таблици, и едит конечно лишнее но пусть будет ;}


 
sniknik ©   (2005-05-25 18:28) [14]

и еще проще это зделать sql запросом (наверное... ;), для jet например конвертация строки с числом и точкой в качестве разделителя в "истинное" число вообще пройдет "автоматом", про остальные поля не скажу (поэтому и "наверное")


 
SergP.   (2005-05-25 18:37) [15]


> В цикле иду от первого символа до последнего и если текущий
> символ = "." то меняю на ","


А зачем? Есть же готовая процедура для поиска и замены....



Страницы: 1 вся ветка

Текущий архив: 2005.06.14;
Скачать: CL | DM;

Наверх




Память: 0.51 MB
Время: 0.073 c
14-1116755818
Igorek
2005-05-22 13:56
2005.06.14
Воскресный флэшовый квест :8-)


4-1114420136
}|{yk
2005-04-25 13:08
2005.06.14
Как зарегистрировать файлы для открытия их определенной программо


6-1111724084
Ozone
2005-03-25 07:14
2005.06.14
Полное описание протокола SMTP


1-1117111852
<Lelik>
2005-05-26 16:50
2005.06.14
про поиск компонентов


14-1116714977
лак
2005-05-22 02:36
2005.06.14
Разреженный вектор