Recent

Author Topic: [SOLVED] Codepage issue in console (only if without Unit CRT)  (Read 736 times)

Hartmut

  • Hero Member
  • *****
  • Posts: 1161
In the past I had rarely issues, that writeln() in console programs showed a wrong codepage for ansistrings on Win7. These programs were larger and used Unit CRT. I did not check, if it worked on Win10.

But now I have the same issue, that a console program shows a wrong codepage, without using Unit CRT and it is reproducible in a very simple demo on Win7 and Win10.

This issue occured always in a way, that a function, which returns an ansistring, returned the correct (!) bytes, but - don't know why - caught a wrong codepage, so the next writeln() showed this string in a wrong codepage, although all bytes of the string had the correct value.

On my Win7 console the default codepage is cp850 = DOS with and without Unit CRT (which I assume is the standard on a German Win7).
On my Win10 console the default codepage is cp1252 = WINDOWS with Unit CRT and cp850 = DOS without Unit CRT (which I assume is the standard on a German Win10).
So a console program without Unit CRT needs cp850 = DOS on my Win7 and Win10.

This is my demo code:
Code: Pascal  [Select][+][-]
  1. {shows wrong codepage in console of Win7 + Win10 without Unit CRT}
  2.  
  3. {$mode objfpc} {$H+}
  4. // uses crt; {repairs the issue}
  5.  
  6.                 {Text 'ÄÖÜ äöü ß' in 2 codepages: }
  7. const Msg_DOS = #$8E#$99#$9A#$20#$84#$94#$81#$20#$E1; {codepage cp850 = DOS}
  8.       Msg_WIN = #$C4#$D6#$DC#$20#$E4#$F6#$FC#$20#$DF; {codepage cp1252 = WINDOWS}
  9. type
  10.    mystring = ansistring;
  11. // mystring = shortstring; {repairs the issue}
  12.  
  13. function hexString(s: mystring): mystring;
  14.    {returns the content of 's' as hex-bytes}
  15.    var z: mystring;
  16.        i: longint;
  17.    begin
  18.    z:='';
  19.    for i:=1 to length(s) do  z:=z + ' ' + hexStr(ord(s[i]),2);
  20.    delete(z,1,1);
  21.    exit(z);
  22.    end;
  23.  
  24. procedure setCodePage_CP_NONE(var s: mystring);
  25.    {repairs the issue}
  26.    begin
  27. {$IF sizeof(s) = sizeof(ansistring)} // does not compile with 'shortstring':
  28.    write('<cp=', system.StringCodePage(s), '>'); {returns '0'}
  29.    system.SetCodePage(RawByteString(s),CP_NONE,false);
  30. {$ENDIF}
  31.    end;
  32.  
  33. function dummy(s: mystring): mystring;
  34.    {should change nothing}
  35.    begin
  36. // setCodePage_CP_NONE(s); {repairs the issue}
  37.    exit(s);
  38.    end;
  39.  
  40. var s: mystring;
  41.  
  42. begin {main}
  43. // assign(Output,''); rewrite(Output); {repairs the issue}
  44. writeln('DOS-codepage: ', Msg_DOS);
  45. s:=dummy(Msg_DOS);
  46. writeln('DOS-codepage with dummy: ', s, ' = ', hexString(s));
  47.  
  48. (* only if you have codepage cp1252 = WINDOWS in your console:
  49. writeln('WIN-codepage: ', Msg_WIN);
  50. s:=dummy(Msg_WIN);
  51. writeln('WIN-codepage with dummy: ', s, ' = ', hexString(s));
  52. *)
  53. end.

I declared const 'Msg_DOS' and 'Msg_WIN' in this way to be independend of the source files codepage.
When I run this program on my Win7 and Win10 console, the output is:
   DOS-codepage: ÄÖÜ äöü ß
   DOS-codepage with dummy: ZTs ""? á = 8E 99 9A 20 84 94 81 20 E1


The 1st line is correct, because 'Msg_DOS' has codepage cp850 = DOS.
The 2nd line is wrong, because function dummy() was called, which returns the correct bytes, but is displayed wrong.
As said, with Unit CRT this issue does not occur!

This issue disappears, when I
 - call assign(Output,'') and rewrite(Output) at start
 - or call setCodePage_CP_NONE() in those rare functions, which have this issue
 - or replace type 'mystring' by 'shortstring'
 - or add Unit CRT (but in the past, when this issue rarely occured, it was always with Unit CRT).

In all 4 cases the output changes to:
   DOS-codepage: ÄÖÜ äöü ß
   <cp=0>DOS-codepage with dummy: ÄÖÜ äöü ß = 8E 99 9A 20 84 94 81 20 E1


This all is with FPC 3.2.2 (but I have the same with 3.2.0 and 3.0.4).

Is there somebody who knows:
(a) why do some functions, e.g. function dummy(), change "something", so that this issue occurs?
(b) but why do they not change this with Unit CRT?
(c) why is calling setCodePage_CP_NONE() neccessary without Unit CRT and not with Unit CRT? - StringCodePage() returns in both cases the same value! ('0')
(d) why does calling before assign(Output,'') and rewrite(Output) solve ths issue?

Thanks in advance.
« Last Edit: June 18, 2026, 05:27:41 pm by Hartmut »

ASerge

  • Hero Member
  • *****
  • Posts: 2510
Re: Codepage issue in console (only if without Unit CRT)
« Reply #1 on: June 16, 2026, 07:52:03 am »
There are several points to consider:
1. What encoding is the source code saved in? For Lazarus, UTF-8 is used by default.
2. What encoding does the compiler assume? The default value is CP_ACP (CP1252 in your case). This can be changed by the {$CODEPAGE} directive.
3. What encoding does RTL suggest (string conversation)? Default CP_ACP. But the GUI calls SetMultiByteConversionCodePage(CP_UTF8).
4. What encoding does the console use? Default CP_OEM (CP850 in your case). This can be changed by system API.
5. What encoding does TextFile? Default CP_OEM. This can be changed by SetTextCodePage.

You example. I'll try to guess.
Msg_DOS chars.
The file is encoded as UTF-8, the compiler assumes CP1252, you want CP850.

Hartmut

  • Hero Member
  • *****
  • Posts: 1161
Re: Codepage issue in console (only if without Unit CRT)
« Reply #2 on: June 16, 2026, 10:20:19 am »
Thanks a lot ASerge for your reply.

There are several points to consider:
1. What encoding is the source code saved in? For Lazarus, UTF-8 is used by default.
With this particular demo I get exactly the same results, if I save the source file as UTF8 or as cp850. The only non ASCII characters are in a comment in line 6, so I assume that they don't matter.
Question:
Is the source file encoding really involved in this particular demo, because const 'Msg_DOS' is declared via '#$xx' codes?

Quote
2. What encoding does the compiler assume? The default value is CP_ACP (CP1252 in your case). This can be changed by the {$CODEPAGE} directive.
I nowhere use the {$CODEPAGE} directive in all of my sources and in this demo, so I guess it's 'CP_ACP'.
Question:
Why do you say, that CP_ACP would be CP1252 in my case? Where does this value come from? Is this a "world wide const" on every OS? Or related to something?

Quote
3. What encoding does RTL suggest (string conversation)? Default CP_ACP. But the GUI calls SetMultiByteConversionCodePage(CP_UTF8).
As said all issues occured in console programs, so SetMultiByteConversionCodePage(CP_UTF8) in GUI programs from my understanding should not matter.
Question:
With 'encoding for string conversation' do you mean function system.StringCodePage()? This function always returned '0' = 'CP_ACP' - both without Unit CRT (when the issue occurs) and also with Unit CRT (when the issue does not occur), as I wrote.

Quote
4. What encoding does the console use? Default CP_OEM (CP850 in your case). This can be changed by system API.
For this particular demo the console has cp850 both on Win7 and Win10 and in the mentioned rare issues in the past on Win7 it was also cp850. I know that this could be changed, but I definitely do not want this. One of the many reasons is, that my programs shall run also on other German Windows systems, which also have cp850.

Quote
5. What encoding does TextFile? Default CP_OEM. This can be changed by SetTextCodePage.
I nowhere use SetTextCodePage() in all of my sources and in this demo.
I added
Code: Pascal  [Select][+][-]
  1. writeln(GetTextCodePage(OUTPUT));
to my demo. It shows '850'. So from my understanding this is correct (because const 'Msg_DOS' has cp850 too).
Question:
Is the value of GetTextCodePage(OUTPUT) the encoding, which writeln() "uses" for every output?

Quote
You example. I'll try to guess.
Msg_DOS chars.
The file is encoded as UTF-8, the compiler assumes CP1252, you want CP850.
Sorry, I don't understand:
 - the source file is pure ASCII (beside of 1 comment), so I assume that this would not matter
 - const 'Msg_DOS' is encoded as cp850, so from my understanding it should work on a cp850 console
 - if I write 'Msg_DOS' directly (line 44), it works correctly
 - only if function dummy() is involved (line 45), the issue occurs
 - but this issue occurs only without Unit CRT, is does not occur with Unit CRT.

Here are still my older questions:
(a) why do some functions, e.g. function dummy(), change "something", so that this issue occurs?
(b) but why do they not change this with Unit CRT?
(c) why is calling setCodePage_CP_NONE() neccessary without Unit CRT and not with Unit CRT? - StringCodePage() returns in both cases the same value! ('0')
(d) why does calling before assign(Output,'') and rewrite(Output) solve ths issue?

ASerge

  • Hero Member
  • *****
  • Posts: 2510
Re: Codepage issue in console (only if without Unit CRT)
« Reply #3 on: June 16, 2026, 12:13:36 pm »
In the first case, Writeln outputs a ShortString. It does not contain a code page and is displayed unchanged. With or without CRT.
In the second case, ShortString is converted to AnsiString. In fact, the compiler includes this converted string in a binary file and performs a simple assignment. The function does nothing with the string.
But(!) Writeln converts the CP_ACP string (which is used by the compiler by default) to the CP_OEM string (which is used by default for Output).
How to fix:

1. Use a CRT that uses CP_ACP.
2. Explicitly set CP_ACP for Output.
3. Set the OEM or nothing code page (RawByteString) for the string without conversion.
Code: Pascal  [Select][+][-]
  1. {$mode objfpc} {$H+}
  2. {$APPTYPE CONSOLE}
  3.  
  4. //uses Crt;
  5.  
  6. const CText = #$8E#$99#$9A#$20#$84#$94#$81#$20#$E1;
  7.  
  8. var
  9.   S: string;
  10. begin
  11.   Writeln('ShortString: ', CText);
  12.   S := CText;
  13.   Writeln('AnsiString with CP_ACP and CP_OEM console: ', S);
  14.   SetTextCodePage(Output, CP_ACP);
  15.   Writeln('AnsiString with CP_ACP and CP_ACP console: ', S);
  16.   SetTextCodePage(Output, CP_OEMCP); // back
  17.   SetCodePage(RawByteString(S), 850, False); // False - no conversion
  18.   Writeln('AnsiString with CP_OEM and CP_OEM console: ', S);
  19.   ReadLn;
  20. end.


« Last Edit: June 16, 2026, 04:26:19 pm by ASerge »

Hartmut

  • Hero Member
  • *****
  • Posts: 1161
Re: Codepage issue in console (only if without Unit CRT)
« Reply #4 on: June 16, 2026, 04:19:24 pm »
Thanks again ASerge for your reply.

But(!) Writeln converts the CP_ACP string (which is used by the compiler by default) to the CP_OEM string (which is used by default for Output).
This sentence looks very important but I still have difficulties to understand you, because this stuff is completely new for me:
 - so it seems, that not function dummy(), but instead procedure Writeln() is "the bad guy", who automatically does the (in my case) unwanted changes to the string, before it is displayed?
 - what is an "CP_ACP string"? Do have all ansistrings by default always have this "property"? Who decides and when, which codepage is meant by "CP_ACP"?
 - Who decides and when, which codepage is meant by "CP_OEM"?

Quote
Code: Pascal  [Select][+][-]
  1. SetTextCodePage(Output, CP_ACP);
  2. Writeln('AnsiString with CP_ACP and CP_ACP console: ', S);
  3.  
Looks like above "SetTextCodePage(Output, CP_ACP)" solves the issue.

As said, in the past I had rarely issues in some programs, that writeln() in console programs showed a wrong codepage for ansistrings. I know, that my sources contain a lot of places, where OUTPUT is changed, e.g. by switching to assignCRT(Output), where e.g. colors are needed or switching to assign(Output,'') when e.g. output redirection should be possible or temporary switching to assign(Output,filename) when writeln() shall instead write into a disk file etc.
Question:
 - would it be enough, to call "SetTextCodePage(Output, CP_ACP)" only once at program start (which would be a moderate amount of work)? Or would I have to repeat it after every assign(Output) and assignCRT(Output) = much more work?

I found out, that setting 'DefaultSystemCodePage' to the OUTPUT-codepage seems to solve the issue too:
Code: Pascal  [Select][+][-]
  1. if GetTextCodePage(OUTPUT) <> DefaultSystemCodePage then
  2.    SetMultiByteConversionCodePage(GetTextCodePage(OUTPUT));

From my understanding, I assume, that this "solution" would be always neccessary only once at program start.
Questions:
 - is this correct for console programs?
 - do you see a difference, that the "consequences" of one of these 2 "solutions" is significantly better than the other?

ASerge

  • Hero Member
  • *****
  • Posts: 2510
Re: Codepage issue in console (only if without Unit CRT)
« Reply #5 on: June 16, 2026, 04:54:05 pm »
- what is an "CP_ACP string"? Do have all ansistrings by default always have this "property"? Who decides and when, which codepage is meant by "CP_ACP"?
If the source file does not contain {$CODEPAGE} and the UTF8 BOM, then the compiler uses CP_ACP for all string constants.

Quote
- Who decides and when, which codepage is meant by "CP_OEM"?
This is default for console applications in Windows.

Quote
Question:
 - would it be enough, to call "SetTextCodePage(Output, CP_ACP)" only once at program start (which would be a moderate amount of work)? Or would I have to repeat it after every assign(Output) and assignCRT(Output) = much more work?
After every.

Quote
Code: Pascal  [Select][+][-]
  1. if GetTextCodePage(OUTPUT) <> DefaultSystemCodePage then
  2.    SetMultiByteConversionCodePage(GetTextCodePage(OUTPUT));

From my understanding, I assume, that this "solution" would be always neccessary only once at program start.
Questions:
 - is this correct for console programs?
 - do you see a difference, that the "consequences" of one of these 2 "solutions" is significantly better than the other?
Yes, it's correct.
For me better use UTF8 :)

Hartmut

  • Hero Member
  • *****
  • Posts: 1161
Re: Codepage issue in console (only if without Unit CRT)
« Reply #6 on: June 16, 2026, 08:22:09 pm »
- what is an "CP_ACP string"? Do have all ansistrings by default always have this "property"? Who decides and when, which codepage is meant by "CP_ACP"?
If the source file does not contain {$CODEPAGE} and the UTF8 BOM, then the compiler uses CP_ACP for all string constants.
Until now I thought, we were talking always about CP_ACP "property" of ansistring variables. Now I'm surprised, that you write 'constants'.
 - does this mean, that all string constants also have a "codepage"? And for source files without {$CODEPAGE} and without UTF8 BOM this "codepage" always is CP_ACP?
 - and if I assign such a string constant to an ansistring variable: is this constant's "codepage" then copied or inherited to the ansistring variable's codepage?
 - but the value of 'CP_ACP' is '0' which from my understanding is not an in reality existing codepage. Is this maybe some kind of "placeholder"? Which is whensoever replaced by a real existing codepage? If yes: by which codepage is it replaced and where comes this replace-value from?

Quote
Quote
- Who decides and when, which codepage is meant by "CP_OEM"?
This is default for console applications in Windows.
Sorry, I don't understand. I assume, you mean 'CP_OEMCP', not 'CP_OEM'?
The value of 'CP_OEMCP' is '1', which from my understanding is also not an in reality existing codepage. Is this maybe also some kind of "placeholder"? Which is whensoever replaced by a real existing codepage? If yes: by which codepage is it replaced and where comes this replace-value from?

ASerge

  • Hero Member
  • *****
  • Posts: 2510
Re: Codepage issue in console (only if without Unit CRT)
« Reply #7 on: June 16, 2026, 11:37:57 pm »
- does this mean, that all string constants also have a "codepage"? And for source files without {$CODEPAGE} and without UTF8 BOM this "codepage" always is CP_ACP?
Yes.

Quote
- and if I assign such a string constant to an ansistring variable: is this constant's "codepage" then copied or inherited to the ansistring variable's codepage?
A new AnsiString variable is created with a code page equal to DefaultSystemCodePage. And if the code page of the constant is different, then the conversion will occur.
In fact, the conversion only happens when the reference count is changed. If the procedures use strings without modification (the const parameter), then a new string is not created.
Example:
Code: Pascal  [Select][+][-]
  1. {$APPTYPE CONSOLE}
  2. {$LONGSTRINGS ON}
  3.  
  4. const
  5.   CText = 'Test';
  6.  
  7. function Test(const S: string): string;
  8. begin
  9.   Result := S;
  10.   Writeln(StringRefCount(Result));
  11. end;
  12.  
  13. begin
  14.   Test(Test(Test(CText)));
  15.   Readln;
  16. end.
Print -1 (the reference count for const) three times.

Quote
- but the value of 'CP_ACP' is '0' which from my understanding is not an in reality existing codepage. Is this maybe some kind of "placeholder"? Which is whensoever replaced by a real existing codepage? If yes: by which codepage is it replaced and where comes this replace-value from?
Yes, it is a placeholder for DefaultSystemCodePage. The initial value of which is taken from the operating system.

Quote
Sorry, I don't understand. I assume, you mean 'CP_OEMCP', not 'CP_OEM'?
My mistake, of course, is CP_OEMCP.

Quote
The value of 'CP_OEMCP' is '1', which from my understanding is also not an in reality existing codepage. Is this maybe also some kind of "placeholder"?
The same. Operating system GetOEMCP. In your case, 850.
In fact, GetConsoleCP and GetConsoleOutputCP were used in the console. However, by default, the consoles are configured to use GetOEMCP.


Hartmut

  • Hero Member
  • *****
  • Posts: 1161
Re: Codepage issue in console (only if without Unit CRT)
« Reply #8 on: June 17, 2026, 04:38:50 pm »
Thanks again a lot ASerge for your new infos. Now I understand much more than before. For me was "codepage CP_ACP" a big mystic, not understandable thing. Now I know, that it simly is a placeholder for the current value in variable 'DefaultSystemCodePage'.

Quote
- and if I assign such a string constant to an ansistring variable: is this constant's "codepage" then copied or inherited to the ansistring variable's codepage?
A new AnsiString variable is created with a code page equal to DefaultSystemCodePage. And if the code page of the constant is different, then the conversion will occur.
As we found out, in my demo const 'Msg_DOS' has codepage 'CP_ACP', because the source file is without {$CODEPAGE} and without UTF8 BOM. And codepage 'CP_ACP' is only a placeholder for variable 'DefaultSystemCodePage'. So in my demo both codepages must be equal, so no conversion may occur. This seems to be correct, because in my demo function StringCodePage() in function setCodePage_CP_NONE() shows '0' = 'CP_ACP'.

Quote
Quote
The value of 'CP_OEMCP' is '1', which from my understanding is also not an in reality existing codepage. Is this maybe also some kind of "placeholder"?
The same. Operating system GetOEMCP. In your case, 850.
In fact, GetConsoleCP and GetConsoleOutputCP were used in the console. However, by default, the consoles are configured to use GetOEMCP.
I found GetOEMCP(), GetConsoleCP() and GetConsoleOutputCP() as functions in Unit 'windows'. They all return '850'.

Currently I have only 1 question left:
Here "OEM" seems to mean the same as "console". This puzzled me strange, because I know "OEM" only as "Original Equipment Manufacturer". Can you (or someone else) explain, why the console codepage here is called "OEM codepage"?

Thaddy

  • Hero Member
  • *****
  • Posts: 19499
  • Glad to be alive.
Re: Codepage issue in console (only if without Unit CRT)
« Reply #9 on: June 17, 2026, 05:04:10 pm »
Can you (or someone else) explain, why the console codepage here is called "OEM codepage"?
It is the default codepage that the Original Equipment Manufacturer installs: this may depend on e.g. the Windows license language(s) that the manufacturer has licensed, e.g. Europe, Japan, Korea, China, USA. And these CAN differ a lot: when ordering a cheap Chinese built laptop the CP_OEM can be simplified Chinese. Luckily this could be changed. It is what the manufacturer chooses as default. Except for the license(s), Microsoft has no control over it. The manufacturer has control.
The same thing can happen with any preinstalled OS. It usually depends on the area where hardware is sold with preinstalled OS.
« Last Edit: June 17, 2026, 07:12:10 pm by Thaddy »
Any "programmer" that knows only one programming language is not a programmer

ASerge

  • Hero Member
  • *****
  • Posts: 2510
Re: Codepage issue in console (only if without Unit CRT)
« Reply #10 on: June 17, 2026, 09:36:27 pm »
As we found out, in my demo const 'Msg_DOS' has codepage 'CP_ACP', because the source file is without {$CODEPAGE} and without UTF8 BOM.
No. Msg_DOS is a ShortString. It doesn't have a code page. But the AnsiString created when the function is called does.

Hartmut

  • Hero Member
  • *****
  • Posts: 1161
Re: Codepage issue in console (only if without Unit CRT)
« Reply #11 on: June 18, 2026, 09:28:33 am »
As we found out, in my demo const 'Msg_DOS' has codepage 'CP_ACP', because the source file is without {$CODEPAGE} and without UTF8 BOM.
No. Msg_DOS is a ShortString. It doesn't have a code page. But the AnsiString created when the function is called does.
OK... Does this mean:
 - const Msg_DOS is a ShortString, because it has not more than 255 bytes?
 - but if const Msg_DOS would have more than 255 bytes, then it would be no ShortString and then it would have a codepage?

As I wrote:
Code: Pascal  [Select][+][-]
  1. writeln(Msg_DOS);
shows correct result. But
Code: Pascal  [Select][+][-]
  1. s:=Msg_DOS; // s=ansistring
  2. writeln(s);
shows wrong result.

Is the following correct:
 - command 's:=Msg_DOS' assigns a ShortString to an ansistring and in such a case the ansistring always gets codepage CP_ACP?
 - CP_ACP means variable 'DefaultSystemCodePage' which in my case has '1252'
 - GetTextCodePage(OUTPUT) in my case returns '850'
 - writeln() converts automatically 's' from '1252' to '850' and this is the reason for the wrong result?

ASerge

  • Hero Member
  • *****
  • Posts: 2510
Re: Codepage issue in console (only if without Unit CRT)
« Reply #12 on: June 18, 2026, 11:07:27 am »
- const Msg_DOS is a ShortString, because it has not more than 255 bytes?
At first, Msg_DOS is just a name for a set of characters. Then the compiler encounters a Writeln call that understands the ShortString parameter. Since the string length is less than 255, ShortString is suitable. The compiler then generates a ShortString constant. If the string was longer or there was a function call with an AnsiString parameter, the compiler would generate an AnsiString constant.

Quote
- but if const Msg_DOS would have more than 255 bytes, then it would be no ShortString and then it would have a codepage?
Yes.

Quote
Is the following correct:
 - command 's:=Msg_DOS' assigns a ShortString to an ansistring and in such a case the ansistring always gets codepage CP_ACP?
 - CP_ACP means variable 'DefaultSystemCodePage' which in my case has '1252'
 - GetTextCodePage(OUTPUT) in my case returns '850'
 - writeln() converts automatically 's' from '1252' to '850' and this is the reason for the wrong result?
Yes, in all cases.
In the first case, if the string was not used as a ShortString, only the AnsiString constant is created.

Thaddy

  • Hero Member
  • *****
  • Posts: 19499
  • Glad to be alive.
Re: Codepage issue in console (only if without Unit CRT)
« Reply #13 on: June 18, 2026, 11:48:25 am »
As we found out, in my demo const 'Msg_DOS' has codepage 'CP_ACP', because the source file is without {$CODEPAGE} and without UTF8 BOM.
No. Msg_DOS is a ShortString. It doesn't have a code page. But the AnsiString created when the function is called does.
But even a shortstring can be encoded as such:
Code: Pascal  [Select][+][-]
  1. // cp850 assumed for the console
  2. {$mode objfpc} {$H- string is shortstring now}
  3. {$APPTYPE CONSOLE}
  4. {$codepage cp850}
  5. const CText =  'ޙ𠄔 á'; //literal encoded for cp850, the same as the cumbersome one in your example
  6.  
  7. var
  8.   S: string; // <--- is a shortstring
  9. begin
  10.   Writeln('ShortString: ', CText);
  11.   ReadLn;
  12. end.

So your answer might be confusing: even a shortstring takes the encoding of the console.
In my case it is either cp850 or UTF8. If it is wise to rely on that is a different matter.
This is only to show shortstrings can take an encoding according to codepage.
The string literal const is also shortstring here, not Ansi:
Code: Pascal  [Select][+][-]
  1. {$mode objfpc} {$H- string is shortstring now}
  2. {$APPTYPE CONSOLE}{$codepage cp850}
  3. const CText =  'ޙ𠄔 á'; // same as #$8E#$99#$9A#$20#$84#$94#$81#$20#$E1;
  4. var
  5.   S: shortstring;
  6. begin
  7.   S:= CText;
  8.   Writeln('ShortString: ', S);
  9.   ReadLn;
  10. end.

« Last Edit: June 18, 2026, 12:09:25 pm by Thaddy »
Any "programmer" that knows only one programming language is not a programmer

Hartmut

  • Hero Member
  • *****
  • Posts: 1161
Re: Codepage issue in console (only if without Unit CRT)
« Reply #14 on: June 18, 2026, 05:27:18 pm »
I think now all is clear. Thank you very much ASerge for your continuous help. I set this Topic now to SOLVED.

 

TinyPortal © 2005-2018