Recent

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

dodgebros

  • Jr. Member
  • **
  • Posts: 77
Trying to fine the ASCII code for a single character
« on: March 20, 2019, 10:40:37 pm »
Let me begin by apologizing up front for asking this question here.  The code is from a Delhpi XE project I created in 2013 and now modifying for the client.

The code reads a line of text from a TStringList then it checks each character to determine if the character is upper case.  The line intChar := Ord(strChar);
returns the number 15267980 which of course is not an ascii code for capital letters.  I have searched all day for a solution and have read a lot about Unicode but still no answer so I am here asking for your help with this  :(


Code: Pascal  [Select]
  1. function TFrame3.LineChk(strLineIn: AnsiString): boolean;
  2. var
  3.   alphabet : set of 65..90;
  4.   i: integer;
  5.   intLen: integer;
  6.   intChar: integer;
  7.   strChar: AnsiString;
  8.   boolflag: boolean;
  9.  
  10. begin
  11.   try
  12.     boolflag := true;
  13.     alphabet := [65..90];
  14.     intLen := AnsiPos(',',strLineIn);
  15.  
  16.     for i := 1 to intLen do
  17.       begin
  18.         strChar := AnsiMidStr(strLineIn, i, 1);
  19.         intChar := Ord(strChar);
  20.         if intChar In alphabet then
  21.           begin
  22.             boolflag := true;
  23.           end
  24.         else
  25.           begin
  26.             boolflag := false;
  27.           end;
  28.       end;
  29.     Result := boolflag;
  30.   except
  31.     on E : Exception do
  32.       begin
  33.         showmessage('Exception message = '+E.Message);
  34.       end;
  35.   end;
  36. end;

Bart

  • Hero Member
  • *****
  • Posts: 3379
    • Bart en Mariska's Webstek
Re: Trying to fine the ASCII code for a single character
« Reply #1 on: March 20, 2019, 11:04:57 pm »
Code: Pascal  [Select]
  1. intChar := Ord(strChar);

You take Ord of an AnsiString?
What does that even mean?

That doesn't even compile in freepascal:  "Error: Ordinal expression expected"

To check if a character is an uppercase ASCII character simply check if it is in ['A'..'Z'].
(ASCII only defines 127 characters, evrything above #127 is ANSI and codepage dependant.)

Bart

furious programming

  • Sr. Member
  • ****
  • Posts: 262
  • I click a little.
Re: Trying to fine the ASCII code for a single character
« Reply #2 on: March 20, 2019, 11:31:11 pm »
Code: Pascal  [Select]
  1. function LineCheck(const ALine: String): Boolean;
  2. var
  3.   I: Integer;
  4. begin
  5.   for I := 1 to AnsiPos(',', ALine) - 1 do
  6.     if not (ALine[I] in ['A' .. 'Z']) then
  7.       Exit(False);
  8.      
  9.   Result := True;
  10. end;

Much simpler, but works the same way.

Edit: I added the obligatory brackets, because without them it is impossible to compile this code.
« Last Edit: March 21, 2019, 07:06:29 pm by furious programming »
Lazarus 2.0.0 with FPC 3.0.4, Windows XP (all 32-bit)

BobDog

  • New member
  • *
  • Posts: 35
Re: Trying to fine the ASCII code for a single character
« Reply #3 on: March 21, 2019, 01:36:05 am »
... Identifier Ansipos not found  ...
giving an error.

try maybe alternative:
Code: Pascal  [Select]
  1.  
  2.  
  3.  
  4.  
  5. program seecase;
  6. var s:ansistring='&%$9abcDefghijkLmnopqrStuvwXyz78901m45/<,,>T|uP{}';
  7.  
  8. function capital(s:string):boolean;
  9. var i:integer;
  10. begin
  11. result:=false;
  12. i:=ord(s[1]);
  13. if (i <= 90)  then
  14.   begin
  15. if (i > 64)  then result:=true;
  16. end
  17. end; //capital
  18.  
  19.  
  20.  
  21.  var i:integer;
  22. begin
  23. for i:=1 to length(s) do
  24. begin
  25. write(s[i],' = ',ord(s[i]));
  26. if ( capital(s[i])=true) then write('  upper case');
  27. writeln ;
  28. end;
  29. writeln('press return to end . . .');
  30.  
  31. readln;
  32. end.


« Last Edit: March 21, 2019, 02:02:18 am by BobDog »

furious programming

  • Sr. Member
  • ****
  • Posts: 262
  • I click a little.
Re: Trying to fine the ASCII code for a single character
« Reply #4 on: March 21, 2019, 02:00:48 am »
... Identifier Ansipos not found  ...
giving an error.

Read the documentation: AnsiPos.
Lazarus 2.0.0 with FPC 3.0.4, Windows XP (all 32-bit)

BobDog

  • New member
  • *
  • Posts: 35
Re: Trying to fine the ASCII code for a single character
« Reply #5 on: March 21, 2019, 02:10:12 am »

Thanks.
But I cannot locate the unit sysansi, which I assume is something to do with  sysansih.inc

jamie

  • Hero Member
  • *****
  • Posts: 1351
Re: Trying to fine the ASCII code for a single character
« Reply #6 on: March 21, 2019, 02:36:04 am »
sysutils and StrUtils  units..

BobDog

  • New member
  • *
  • Posts: 35
Re: Trying to fine the ASCII code for a single character
« Reply #7 on: March 21, 2019, 03:08:10 am »

Thanks jamie.
This seems to be similar.
Code: Pascal  [Select]
  1.  
  2.  
  3. program cases;
  4.  
  5.  
  6. function IsCapital(s:ansistring):boolean;
  7. begin
  8. result:=ord(s[1]) in [65 .. 90];
  9. end;
  10.  
  11.  
  12.  var s:ansistring='&%$9abcDefghijkLmnopqrStuvwXyz78901m45/<,,>T|uP{}';
  13.  var i:integer;
  14.  
  15. begin
  16. for i:=1 to length(s) do
  17. begin
  18. write(s[i],' = ',ord(s[i]));
  19. if  IsCapital(s[i]) then write('   UPPER CASE');
  20. writeln ;
  21. end;
  22. writeln('press return to end . . .');
  23.  
  24. readln;
  25. end.




dodgebros

  • Jr. Member
  • **
  • Posts: 77
Re: Trying to fine the ASCII code for a single character
« Reply #8 on: March 21, 2019, 04:03:00 am »
Thank you to all who replied.

Quote
To check if a character is an uppercase ASCII character simply check if it is in ['A'..'Z'].
(ASCII only defines 127 characters, evrything above #127 is ANSI and codepage dependant.)

Thank you, I didn't realize that

Code: Pascal  [Select]
  1. function LineCheck(const ALine: String): Boolean;
  2. var
  3.   I: Integer;
  4. begin
  5.   for I := 1 to AnsiPos(',', ALine) - 1 do
  6.     if not ALine[I] in ['A' .. 'Z'] then
  7.       Exit(False);
  8.      
  9.   Result := True;
  10. end;
  11.  

Could you please explain the ALine bracket I bracket, I've been using AnsiMidStr() for this.

Also, the ['A'..'Z'], so you don't have to declare it as a Set?




furious programming

  • Sr. Member
  • ****
  • Posts: 262
  • I click a little.
Re: Trying to fine the ASCII code for a single character
« Reply #9 on: March 21, 2019, 04:53:14 am »
Could you please explain the ALine bracket I bracket, I've been using AnsiMidStr() for this.

String is like a one-dimensional array — you can refer to individual characters by using the numeric index given in brackets, as I showed in the example. Result of ALine[Index] is char (not numerical code), so you can compare it directly with another character or check if this char is in set of characters.

Quote
Also, the ['A'..'Z'], so you don't have to declare it as a Set?

The ['A'..'Z'] is a hadrcoded set of char, so you don't need to declare it as a separate variable or constant. The same as in the string/char/numerical literal case.

If you want to program, you must learn the basics of the language.
Lazarus 2.0.0 with FPC 3.0.4, Windows XP (all 32-bit)

dodgebros

  • Jr. Member
  • **
  • Posts: 77
Re: Trying to fine the ASCII code for a single character
« Reply #10 on: March 21, 2019, 05:15:49 am »
Quote
If you want to program, you must learn the basics of the language.

Thanks for explaining these. Yes, my knowledge of Object Pascal is lacking and sometimes I need someone to explain things.  I hope to keep improving!

bytebites

  • Full Member
  • ***
  • Posts: 178
Re: Trying to fine the ASCII code for a single character
« Reply #11 on: March 21, 2019, 05:40:11 am »
Code: Pascal  [Select]
  1.  if not ALine[I] in ['A' .. 'Z'] then
gives
Quote
Error: Type mismatch
correct
Code: Pascal  [Select]
  1.  if not (ALine[I] in ['A' .. 'Z']) then

dodgebros

  • Jr. Member
  • **
  • Posts: 77
Re: Trying to fine the ASCII code for a single character
« Reply #12 on: March 21, 2019, 04:33:35 pm »
THANK YOU! :D

Martin_fr

  • Administrator
  • Hero Member
  • *
  • Posts: 5237
    • wiki
Re: Trying to fine the ASCII code for a single character
« Reply #13 on: March 21, 2019, 04:55:58 pm »
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.

"string[x]" and/or the "in" operator will not work if you need to find upper/lower umlauts äöü/ÄÖÜ. The same for accented chars, or the Turkish uppercase dotted I, or lowercase not-dotted i. And of course not, if you look at other scriptures.

Then you can get a codepoint (google/search the forum - not the same as a char) using Utf8Copy, Utf8Pos, (IIRC) Utf8CodePointLenght....
"Ord" will not work on them, as the return strings (codepoints are stored as strings). But the utf8 helper units may have a function to get the value of such a codepoint.

Alternative you can convert to utf16, or utf32. But you still work with codepoints, not chars. And in case of utf16 there are also surrogates. But they do probably not pertain to the upper/lowercase issue. (They are for real exotic stuff like Egyptian hieroglyphs. Not sure if any of those have an upper/lower distinction ;) )

Remy Lebeau

  • Hero Member
  • *****
  • Posts: 585
    • Lebeau Software
Re: Trying to fine the ASCII code for a single character
« Reply #14 on: March 21, 2019, 06:05:43 pm »
Code: Pascal  [Select]
  1.  
  2. function IsCapital(s:ansistring):boolean;
  3. begin
  4. result:=ord(s[1]) in [65 .. 90];
  5. end;
  6.  
  7. var s:ansistring='&%$9abcDefghijkLmnopqrStuvwXyz78901m45/<,,>T|uP{}';
  8.  
  9. if  IsCapital(s[i]) then write('   UPPER CASE');
  10.  

Why are you converting an AnsiChar to an AnsiString just to compare its 1st AnsiChar?  IsCapital() should take an AnsiChar (better, a Char) as input instead:

Code: [Select]
function IsCapital(ch: Char):boolean;
begin
  Result := ord(ch) in [65 .. 90];
  // or: Result := ch in ['A'..'Z'];
end;

var s: string = '&%$9abcDefghijkLmnopqrStuvwXyz78901m45/<,,>T|uP{}';

if IsCapital(s[i]) then write('   UPPER CASE');
Remy Lebeau
Lebeau Software - Owner, Developer
Internet Direct (Indy) - Admin, Developer (Support forum)