Recent

Author Topic: Trying to fine the ASCII code for a single character  (Read 6102 times)

furious programming

  • Hero Member
  • *****
  • Posts: 852
Re: Trying to fine the ASCII code for a single character
« Reply #15 on: March 21, 2019, 07:00:38 pm »
correct
Code: Pascal  [Select][+][-]
  1.  if not (ALine[I] in ['A' .. 'Z']) then

That's right. Sorry for this, I wrote the code in the memo for answers and did not pay attention to the brackets. Oxygene has a good solution for this — the not in operator:

Code: Pascal  [Select][+][-]
  1. if ALine[I] not in ['A' .. 'Z'] then

And no brackets are needed. But this operator is not supported in Free Pascal.

Note that this only works for a-z / A-Z.

This is because in UTF-8 a-z are encoded in one octet (1 byte, or one pascal "char").
This is part of UTF-8
- The ASCII chars (ordinary value below 128 (excluding 128)) are the same
- no other codepoint (char) in utf-8 contains an octet (byte) with a value between 0 and 127.

[...]

Yep, good that you mentioned it. I did not write about it myself because I took it for granted. But even if the input string contains multibyte codepoints, this way of iterating over the characters also applies (in the case of UTF-8):

Code: Pascal  [Select][+][-]
  1. function CountASCIIChars(const ALine: String): Integer;
  2. var
  3.   Character: Char;
  4. begin
  5.   Result := 0;
  6.  
  7.   for Character in ALine do
  8.     Result += Ord(Character in [#0 .. #127]);
  9. end;
  10.  
  11. CountASCIIChars('zażółć gęślą jaźń'); // gives "8", which is true

Unless we're looking for a multibyte value, then we have to use a different algorithm.
« Last Edit: March 21, 2019, 07:14:24 pm by furious programming »
Lazarus 3.2 with FPC 3.2.2, Windows 10 — all 64-bit

Working solo on an acrade, action/adventure game in retro style (pixelart), programming the engine and shell from scratch, using Free Pascal and SDL. Release planned in 2026.

ASerge

  • Hero Member
  • *****
  • Posts: 2222
Re: Trying to fine the ASCII code for a single character
« Reply #16 on: March 21, 2019, 07:13:33 pm »
If the speed is not critical, then taking into account the remark @Martin_fr:
Code: Pascal  [Select][+][-]
  1. function HasCapitalLetters(const S: string): Boolean;
  2. begin
  3.   Result := AnsiLowerCase(S) <> S;
  4. end;

engkin

  • Hero Member
  • *****
  • Posts: 3112
Re: Trying to fine the ASCII code for a single character
« Reply #17 on: March 21, 2019, 10:49:10 pm »
Code: Pascal  [Select][+][-]
  1. program Project1;
  2.  
  3. {$mode objfpc}{$H+}
  4.  
  5. uses
  6.   sysutils, character;
  7.  
  8. function LineCheck(const ALine: String): Boolean;
  9. var
  10.   UTF16String: UnicodeString;
  11.   Limit, i: SizeInt;
  12. begin
  13.   Limit := AnsiPos(',', ALine) - 1;
  14.   UTF16String := UnicodeString(Copy(ALine, 1, Limit));
  15.   i := 1;
  16.   while i<=Length(UTF16String) do
  17.   begin
  18.     if not TCharacter.IsUpper(UTF16String, i) then
  19.       exit(false);
  20.  
  21.     if TCharacter.IsSurrogate(UTF16String[i]) then
  22.       inc(i,2)
  23.     else
  24.       inc(i);
  25.   end;
  26.  
  27.   Result := True;
  28. end;
  29.  
  30. var
  31.   s: string;
  32. begin
  33.   SetMultiByteConversionCodePage(65001);
  34.  
  35.   s := 'abc,';
  36.   WriteLn(LineCheck(s));  //False
  37.  
  38.   s := 'ABC,';
  39.   WriteLn(LineCheck(s));  //True
  40.  
  41.   s := 'ÜĞğ,';
  42.   WriteLn(LineCheck(s));  //False
  43.  
  44.   s := 'ÜĞ,';
  45.   WriteLn(LineCheck(s));  //True
  46.  
  47.   s := 'äöü,';
  48.   WriteLn(LineCheck(s));  //False
  49.  
  50.   s := 'ÄÖÜ,';
  51.   WriteLn(LineCheck(s));  //True
  52.  
  53.   s := '12B,';
  54.   WriteLn(LineCheck(s));  //False
  55.  
  56.   ReadLn;
  57. end.

 

TinyPortal © 2005-2018