Форум: "Основная";
Текущий архив: 2005.06.14;
Скачать: [xml.tar.bz2];
ВнизПосимвольно формировать 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;
Скачать: [xml.tar.bz2];
Память: 0.5 MB
Время: 0.043 c