[fpc-pascal] Concatenating CP Strings

Sven Barth pascaldragon at googlemail.com
Sun Sep 16 12:35:36 CEST 2018

On 9/15/18 10:12 PM, Martok wrote:
> And another one:
> var
>   f: TextFile;
>   s: string;
> begin
>   AssignFile(f, 'a_file.txt');
>   SetTextCodePage(f, 866);
>   Reset(f);
>   ReadLn(f, s);
>   WriteLn(StringCodePage(s));
>   readln;
> end.
> That is rather useless...

No, it is not. The code page of "String" is CP_ACP, so that means that
every string that gets assigned to it gets converted to the code page
that was at startup of the RTL determined to be the system code page (or
whatever was set using SetMultiByte*CodePage() before the assignment).

If you want the content to *be* in code page 866 without any tricks then
you need to declare a AnsiString with that code page and use that:

=== code begin ===

  TCP866String = type AnsiString(866);

  f: TextFile;
  s: TCP866String;
  Assign(f, 'a_file.txt');
  SetTextCodePage(f, 866);
  ReadLn(f, s);

=== code end ===

This will print "866" and no conversions of the file will have been
done. Alternatively you can use TUTF8String (which is a "type
AnsiString(CP_UTF8)") and it will print 65001 with a lossless conversion
to UTF-8 having occurred.

TL;DR: "AnsiString"/"String" is a type that has the code page that was
determined at startup, not one that turns itself into whatever code page
gets thrown at it

(Note: there are situations where the static code page of the string and
the dynamic don't match, but they're seldom and exceptions from the rule)


More information about the fpc-pascal mailing list