Форум программистов
 

Восстановите пароль или Зарегистрируйтесь на форуме, о проблемах и с заказом рекламы пишите сюда - alarforum@yandex.ru, проверяйте папку спам!

Вернуться   Форум программистов > Delphi программирование > Общие вопросы Delphi
Регистрация

Восстановить пароль
Повторная активизация e-mail

Купить рекламу на форуме - 42 тыс руб за месяц

Ответ
 
Опции темы Поиск в этой теме
Старый 08.06.2021, 15:30   #1
Kronos913
Форумчанин
 
Регистрация: 10.02.2021
Сообщений: 603
По умолчанию Превращение короткой строки в число

Немного лирики "зачем это вообще надо"
Итак, оператор case отказывается работать со строками. Цепочку If'ов городить желания мало

А конкретная задача - в зависимости от расширения файла файла, нужно выполнять разные действия

Решение, которое я придумал - сделать функцию, которая превращает последние 4 символа строки в переменную LongWord

Традиционно, все через UpCase потому что иногда файлы подписывают '.jpg', иногда '.JPG', а иногда и, '.Jpg'

Код:
function UpString4ToLongWord(const s:string): LongWord;
const
  Coefs: array[0..3] of LongWord = (1, 256, 65536, 16777216);
var
  i, j:byte;
Begin
 Result:=0;
 j:=length(s);
 If j>0 then begin
  For i:=0 to min(4, j)-1 do begin
   Inc(Result, (Byte(UpCase(s[j-i]))*Coefs[i]));
  end;
 end;
End;
Вопрос: оптимален ли этот код? Или можно его улучшить?

И на счет этой строки:
Код:
 j:=length(s);
Что лучше: 5 раз дергать функцию length, или же 1 раз присвоить ее переменной?
Kronos913 вне форума Ответить с цитированием
Старый 08.06.2021, 16:00   #2
Kronos913
Форумчанин
 
Регистрация: 10.02.2021
Сообщений: 603
По умолчанию

Вообще, может быть как-то можно обратиться напрямую. к памяти, и скопировать оттуда биты строки как LongWord ?
Kronos913 вне форума Ответить с цитированием
Старый 08.06.2021, 16:12   #3
BDA
МегаМодератор
СуперМодератор
 
Аватар для BDA
 
Регистрация: 09.11.2010
Сообщений: 7,285
По умолчанию

А так не пойдет?
Код:
uses StrUtils;
...
case AnsiIndexStr(AnsiUpperCase(RightStr(s, 4)), ['.JPG', '.BMP']) of
  0: ShowMessage('jpg');
  1: ShowMessage('bmp');
end;
Пишите язык программирования - это форум программистов, а не экстрасенсов. (<= это подпись )
BDA вне форума Ответить с цитированием
Старый 08.06.2021, 16:26   #4
Kronos913
Форумчанин
 
Регистрация: 10.02.2021
Сообщений: 603
По умолчанию

Супер! Функция RightStr - просто находка
Только такой вопрос: в случае, если случайно зайдет пустая строка (или строка короче 4 символов), что тогда выдаст RightStr ?
Kronos913 вне форума Ответить с цитированием
Старый 08.06.2021, 16:35   #5
BDA
МегаМодератор
СуперМодератор
 
Аватар для BDA
 
Регистрация: 09.11.2010
Сообщений: 7,285
По умолчанию

По сути это обёртка над Copy, так что ведёт себя также - вернёт столько символов, сколько есть в строке (или пустую строку).
Пишите язык программирования - это форум программистов, а не экстрасенсов. (<= это подпись )
BDA вне форума Ответить с цитированием
Старый 08.06.2021, 16:37   #6
Kronos913
Форумчанин
 
Регистрация: 10.02.2021
Сообщений: 603
По умолчанию

Кстати, код самой функции привел к такому виду, но может можно еще лучше сделать?

Код:
Function UpString4ToLongWord(const s:string): LongWord;
var
  i, j:byte;
  c:array [0..3] of char;
Begin
 j:=length(s);
 For i:=0 to 3 do begin
     If i<j then c[i]:=UpCase(s[j-i])
     Else c[i]:=#0;
 end;
 Result:=LongWord(c);
End;
Kronos913 вне форума Ответить с цитированием
Старый 08.06.2021, 16:59   #7
Kronos913
Форумчанин
 
Регистрация: 10.02.2021
Сообщений: 603
По умолчанию

Цитата:
Сообщение от BDA Посмотреть сообщение
По сути это обёртка над Copy, так что ведёт себя также - вернёт столько символов, сколько есть в строке (или пустую строку).
Нашел ее листинг...
Ну у меня есть такая самодельная функция в программе:

Код:
function rasr(const s:string; const a:byte): string;
begin
 If (a<length(s)) then begin
  result:=AnsiUpperCase(Copy(s, length(s)-a, a+1));
 end else result:='';
end;
И я теперь задумался, есть ли смысл переделывать половину программы =)
Kronos913 вне форума Ответить с цитированием
Старый 08.06.2021, 17:08   #8
Kronos913
Форумчанин
 
Регистрация: 10.02.2021
Сообщений: 603
По умолчанию

Цитата:
Сообщение от BDA Посмотреть сообщение
А так не пойдет?
Код:
uses StrUtils;
...
case AnsiIndexStr(AnsiUpperCase(RightStr(s, 4)), ['.JPG', '.BMP']) of
  0: ShowMessage('jpg');
  1: ShowMessage('bmp');
end;
А что выдаст AnsiIndexStr, если строки не окажется в списке?
Kronos913 вне форума Ответить с цитированием
Старый 08.06.2021, 19:38   #9
BDA
МегаМодератор
СуперМодератор
 
Аватар для BDA
 
Регистрация: 09.11.2010
Сообщений: 7,285
По умолчанию

Цитата:
Сообщение от Kronos913 Посмотреть сообщение
может можно еще лучше сделать?
Не знаю, лучше ли, но можно так:
Код:
function StrToLongWord(const s: string): LongWord;
var
  tmp_s: string;
begin
  Result := 0;
  tmp_s := AnsiUpperCase(RightStr(s, 4));
  Move(tmp_s[1], Result, Length(tmp_s));
end;
Правда, результат зеркальный получается (к вопросу о порядке байтов в памяти, представляющих многобайтовое число), но если использовать одну функцию везде, то это не важно.
Цитата:
Сообщение от Kronos913 Посмотреть сообщение
есть ли смысл переделывать половину программы =)
Надеюсь, вы пользуетесь системой контроля версий. Если уж занимаетесь рефакторингом, то можно и переделать.
Цитата:
Сообщение от Kronos913 Посмотреть сообщение
А что выдаст AnsiIndexStr, если строки не окажется в списке?
Ответы на такие вопросы быстрее узнать у интернета, так как это не какая-то самописная функция с запутанным кодом. AnsiIndexStr вернет -1, если строки нет в списке.
Пишите язык программирования - это форум программистов, а не экстрасенсов. (<= это подпись )
BDA вне форума Ответить с цитированием
Старый 08.06.2021, 20:11   #10
Kronos913
Форумчанин
 
Регистрация: 10.02.2021
Сообщений: 603
По умолчанию

Кстати, я не совсем понимаю, почему результат становится зеркальным.
Потому у меня и массив чаров делается в зеркальном порядке для компенсации
Kronos913 вне форума Ответить с цитированием
Ответ


Купить рекламу на форуме - 42 тыс руб за месяц

Опции темы Поиск в этой теме
Поиск в этой теме:

Расширенный поиск


Похожие темы
Тема Автор Раздел Ответов Последнее сообщение
[C#] Найти сумму длин самой короткой и первой строк. Pupil1 Помощь студентам 0 19.06.2019 20:45
В каждой строке вибираеться минимальное число, а затем среди этих чисел вибираеться максимально. Вивести на экран номер строки в котором находится это число. Анастасия3006 Помощь студентам 1 26.12.2016 01:20
Ввести число N. Вывести N строк с номером строки, двоеточием и набором чисел от 1 до N+1-k (где k-номер строки) ( в С ) Eduard12345 Помощь студентам 1 11.10.2013 07:25
подсчитать количество символов в самой короткой группе, в строке, состоящей из групп нулей и единиц misher Помощь студентам 6 22.10.2012 09:53
В матрице найти число положительных элементов указанной строки и умножить это число на элементы указанного столбца. (Паскаль) Julichka1k Помощь студентам 4 18.12.2011 20:35