Главная страница
    Top.Mail.Ru    Яндекс.Метрика
Форум: "Основная";
Текущий архив: 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
4-1114153640
needle
2005-04-22 11:07
2005.06.14
как определить более подробный тип диска


1-1116944852
sergg
2005-05-24 18:27
2005.06.14
Запуск файлов Word Excel и т.д.


1-1117448692
Garfunkel
2005-05-30 14:24
2005.06.14
Отображение русских букв


1-1117346604
Aldor
2005-05-29 10:03
2005.06.14
Чтение свойства - всем, запись - только потомкам


14-1117195061
Alena
2005-05-27 15:57
2005.06.14
Не работает exe-шник





Afrikaans Albanian Arabic Armenian Azerbaijani Basque Belarusian Bulgarian Catalan Chinese (Simplified) Chinese (Traditional) Croatian Czech Danish Dutch English Estonian Filipino Finnish French
Galician Georgian German Greek Haitian Creole Hebrew Hindi Hungarian Icelandic Indonesian Irish Italian Japanese Korean Latvian Lithuanian Macedonian Malay Maltese Norwegian
Persian Polish Portuguese Romanian Russian Serbian Slovak Slovenian Spanish Swahili Swedish Thai Turkish Ukrainian Urdu Vietnamese Welsh Yiddish Bengali Bosnian
Cebuano Esperanto Gujarati Hausa Hmong Igbo Javanese Kannada Khmer Lao Latin Maori Marathi Mongolian Nepali Punjabi Somali Tamil Telugu Yoruba
Zulu
Английский Французский Немецкий Итальянский Португальский Русский Испанский