Порівняння рядків - як правильно

Порівняння рядків - як правильно?

Цікавить таке питання - як потрібно правильно порівнювати між собою на рівність рядки string?

Я зазвичай порівнюю по-старому як S1 = S2. іноді привожу до одного регістру через LowerCase.

Але помітив що в ісходнікак VCL рядки часто порівнювати не з =. а з допомогою функцій CompareStr. AnsiCompareStr. AnsiCompareText і подібних.

Так чим же загрожує порівнювання S1 = S2 і як правильно порівнювати рядки?

AnsiCompareStr порівнює з урахуванням локалі. CompareStr може не працювати на національних алфавітах


> Як правильно порівнювати рядки?

S1 = S2

все інше має відношення до порівняння тексту. бо рядок це тип змінної

Якщо тільки на рівність і без урахування тек.локалі, то варіант S1 = S2 цілком достатній.

CompareStr - регістрочувствітельное порівняння на менше / одно / більше без урахування тек.локалі

CompareText - регістроне чутливе порівняння на менше / одно / більше без урахування тек.локалі

AnsiCompareStr - регістрочувствітельное порівняння на менше / одно / більше з урахуванням тек.локалі

AnsiCompareText - регістроне чутливе порівняння на менше / одно / більше з урахуванням тек.локалі.

Що "правильніше" - це вирішувати тобі в кожному конкретному випадку.

"" ABC і "ABC # XA0; "- це різні або однакові рядки?

Тобто якщо мені потрібно порівнювати на посимвольного рівність - то метод S1 = S2 цілком робочий?

І ще збентежило те, що для CompareStr використовується функція, написана на асемблері, але вже для AnsiCompareStr - функція WinAPI.


> Тобто якщо мені потрібно порівнювати на посимвольного рівність
> - то метод S1 = S2 цілком робочий?

а в чому сумніви? звичайно

> І ще збентежило те, що для CompareStr використовується функція,
> Написана на асемблері, але вже для AnsiCompareStr - функція
> WinAPI

а чого ніяковіти? CompareString - вона як раз з урахуванням локалі може порівнювати

Фокуса немає, тут потрібен ще й TRIM крім регістронезавісімого порівняння.

Ось для прикладу шматок коду:

const
# XA0; PARAM_Username = "user_name";
# XA0; PARAM_Password = "password";

function GetParamValue (Params: TStrings; const ParamName: string; Erase: boolean = false): string;
var
# XA0; i: integer;
begin
# XA0; result: = "";
# XA0; for i: = Params.Count -1 downto 0 do
// а можна написати і ось так
// # XA0; if Params.Names [i] = ParamName
# XA0; # XA0; if # XA0; 0 = AnsiCompareText (Params.Names [i], ParamName)
# XA0; # XA0; then begin
# XA0; # XA0; # XA0; result: = Params.ValueFromIndex [i];
# XA0; # XA0; # XA0; if Erase
# XA0; # XA0; # XA0; then Params.Delete (i);
# XA0; # XA0; # XA0; break;
# XA0; # XA0; end;
end;

Розумію тепер - що даремно я втілити AnsiCompareText - досить було і простого порівняння :)

> Досить було і простого порівняння

досить було і Params.IndexOfName)

а нафіга Erase при цьому - я не розумію, функція повинна повертати значення, а видаляти - окрема процедура (якщо так хочеться видалити з параметрів)

Це пов'язано з тим, що функція AnsiPos використовує функції StrPos і CompareString. призначені для роботи з рядками PChar.

Erase при цьому нафіга - для того щоб відокремити оброблені параметри від необроблених. Наприклад потрібно просто дізнатися з параметрів ім'я користувача - для цього досить і Values ​​[ParamName], але іноді ім'я користувача потрібно занести в одне поле - а інші параметри в мемо.

Пам'ять: 0.75 MB
Час: 0.029 c