Форум: "Начинающим";
Текущий архив: 2007.09.30;
Скачать: [xml.tar.bz2];
ВнизПроверить ASCII строку Найти похожие ветки
← →
writebuf(nil); (2007-08-31 17:10) [0]Как проверить ansi-строку на предмет того что она состоит только из символов ASCII, а не является юникодовой, UTF8?
Единственная моя идея - это в цикле проверять:
for i := 0 to Len(str) do
if Ord(str[i]) > $7F then notascii
Но это мне кажется моя ересь. Что-то есть нормальное?
← →
Reindeer Moss Eater © (2007-08-31 17:18) [1]Проверить то, что строка состоит только из какого-то множества символов - это значит убедиться, что в ней нет ни одного другого символа.
поэтому это не ересь:
Единственная моя идея - это в цикле проверять:
← →
Anatoly Podgoretsky © (2007-08-31 18:43) [2]> writebuf(nil); (31.08.2007 17:10:00) [0]
ASCII какой, us или extended?
← →
writebuf(nil); (2007-08-31 18:47) [3]
> ASCII какой, us или extended?
US
← →
Anatoly Podgoretsky © (2007-08-31 19:05) [4]> writebuf(nil); (31.08.2007 18:47:03) [3]
Тогда в него входят символы с кодами 32-127, плюс некоторое неодназначное подмножество из 0-31
Если подмножество не волнует, тогда можешь считать, что если встретился символ с кодом более $7F это уже не ASCII
← →
Slym © (2007-09-03 14:23) [5]для быстроты (оптимизация) можно по 4 байта проверять
var p:PInteger;
begin
p:=pointer(PChar(str));
for i := 0 to Len(str) div 4 do
begin
if (p^ and $80)<>0 then notascii
inc(p)
end;
← →
Slym © (2007-09-03 14:24) [6]if (p^ and $80808080)<>0 then notascii
← →
Sha © (2007-09-03 17:15) [7]> Slym ©
А как быть со строкой "я" ?
← →
umbra © (2007-09-03 17:30) [8]
> Как проверить ansi-строку на предмет того что она состоит
> только из символов ASCII, а не является юникодовой, UTF8?
>
по-моему, вопрос поставлен неверно. Содержимое некоего буфера (строки) нельзя интрепретировать, не зная, что туда попало. UTF-8 и Unicode Определеяются по BOM, но опять таки, ВОМ стоит в началефайла
, а не буфера. В общем, задача в такой постановке, по-моему, неразрешима.
← →
Anatoly Podgoretsky © (2007-09-03 17:42) [9]Ну то что неверно, это мягко сказано
ANSI никак не может быть ни юникодом, ни UTF8, иначе это не ANSI или ASCII
← →
Anatoly Podgoretsky © (2007-09-03 17:44) [10]
> А как быть со строкой "я" ?
Что смущает, код равен FF или для OEM другой, но все равно выше 7F
Автор сделал уточнение
АП> ASCII какой, us или extended?
>
>
> US
← →
Sha © (2007-09-03 17:52) [11]> Anatoly Podgoretsky ©
> Что смущает...
смущает то,
что в [5]-[6] цикл проверки не выполнится ни разу,
и результат функции останется неопределенным.
← →
Anatoly Podgoretsky © (2007-09-03 18:00) [12]Ну это не единственная проблема, но я понимаю, что это как направление.
Теперь я понял, что ты имел ввиду, ну написал бы "z"
А то глаз зацепился за рускую букву
← →
Sha © (2007-09-03 18:04) [13]> Anatoly Podgoretsky ©
> Теперь я понял, что ты имел ввиду, ну написал бы "z"
> А то глаз зацепился за рускую букву
Русская, потому что мне автор телепатировал,
что по умолчанию он собирался сделать результат ASCII )
← →
Sha © (2007-09-03 19:00) [14]> Anatoly Podgoretsky © (03.09.07 18:00) [12]
> ... я понимаю, что это как направление.
тогда как-то так :)
function IsAsciiString(const s: string): boolean;
var
p, q: pchar;
label
NotASCII;
begin;
p:=pointer(s);
if p<>nil then begin;
q:=@p[-SizeOf(integer)]; //Pointer to string length
q:=q+((pInteger(q)^+ (SizeOf(integer)-1)) and -2); //Pointer to the last word
if (pWord(q)^ and $8080)<>0 then goto NotASCII; //Test the last waord
if p<>q then repeat;
if (pInteger(p)^ and $80808080)<>0 then goto NotASCII; //Test current dword
p:=p+SizeOf(integer); //Pointer to the next dword
until p>=q;
end;
Result:=true;
exit;
NotASCII:
Result:=false;
end;
procedure TForm1.Button2Click(Sender: TObject);
const
Captions: array[boolean] of string= ("false", "true");
begin;
Label1.Caption:=Captions[IsAsciiString(Edit1.Text)];
end;
← →
Anatoly Podgoretsky © (2007-09-03 19:31) [15]> Sha (03.09.2007 18:04:13) [13]
А мне телепатировал, что US
← →
Sha © (2007-09-03 20:44) [16]Кстати, тут почти даром дается развертывание цикла,
в итоге обрабатываем по 8 символов за один проход цикла
function IsAsciiString(const s: string): boolean;
var
p: pIntegerArray;
q: pWordArray;
label
NotASCII;
begin;
p:=pointer(s);
if p<>nil then begin;
q:=@pchar(p)[-SizeOf(integer)]; //Pointer to string length
inc(pchar(q),(pInteger(q)^-1) and -2); //Pointer to the last word - 4
if (q[2] and $8080)<>0 then goto NotASCII; //Test the last word
if (pinteger(q)^ and $80808080)<>0 then goto NotASCII; //Test the previous dword
while pchar(p)<pchar(q) do begin;
if (p[0] and $80808080)<>0 then goto NotASCII; //Test the first dword
if (p[1] and $80808080)<>0 then goto NotASCII; //Test the second dword
inc(pchar(p),2*SizeOf(integer)); //Pointer to the next pair of dwords
end;
end;
Result:=true;
exit;
NotASCII:
Result:=false;
end;
← →
Sha © (2007-09-03 21:01) [17]Ну и, наконец, размер цикла можно уменьшить до 18 байт,
если перед ним маску поместить в переменную:m:=$80808080;
Страницы: 1 вся ветка
Форум: "Начинающим";
Текущий архив: 2007.09.30;
Скачать: [xml.tar.bz2];
Память: 0.49 MB
Время: 0.059 c