Tiny
Tiny

Reputation: 419

How do I output the contents of a Set in Pascal?

I'm working with simple sets in Pascal, and simply want to output the contents of a set. Everytime I run the code i get the following error message: 'project1.lpr(17,13) Error: Can't read or write variables of this type'.

here is my code:

  program Project1;

{$mode objfpc}{$H+}

uses
  sysutils;

type TFriends = (Anne,Bob,Claire,Derek,Edgar,Francy);
type TFriendGroup = Set of TFriends;

Var set1,set2,set3,set4:TFriendGroup;    x:integer;

begin
set1:=[Anne,Bob,Claire];
set2:=[Claire,Derek];
set3:=[Derek,Edgar,Francy];
writeln(set1);
readln;
end.

Is there a special method/function to output sets?

thanks

Upvotes: 3

Views: 2880

Answers (2)

Abstract type
Abstract type

Reputation: 1921

You can't directly display the set as a string because there is no type information emitted for it. To do so, your set must be a published property of a class.

Once published in a class, you can use the unit TypInfo to display the set as a string, using the function SetToString(). TypInfo is the FPC unit which does all the compiler reflection things.

Short working example of what you try to do:

program Project1;
{$mode objfpc}{$H+}
uses
  sysutils, typinfo;

type
  TFriends = (Anne,Bob,Claire,Derek,Edgar,Francy);
  TFriendGroup = Set of TFriends;

  TFoo = class
  private
    fFriends: TFriendGroup;
  published
    property Friends: TFriendGroup read fFriends write fFriends;
  end;

Var
  Foo: TFoo;
  FriendsAsString: string;
  Infs: PTypeInfo;

begin
  Foo := TFoo.Create;
  Foo.Friends := [Derek, Edgar, Francy];
  //
  Infs := TypeInfo(Foo.Friends);
  FriendsAsString := SetToString(Infs, LongInt(Foo.Friends), true);
  //
  Foo.Free;
  writeln(FriendsAsString);
  readln;
end.

This program outputs:

[Derek,Edgar,Francy]

To go further:

Upvotes: 3

Marco van de Voort
Marco van de Voort

Reputation: 26356

Free Pascal allows write/writeln() of enums without explicit typinfo calls.

So

{$mode objfpc}  // or Delphi, For..in needs Object Pascal dialect iirc.
var Person :TFriends;

 for Person in Set1 do
    writeln(Person);

works fine.

Using WriteStr this can also be written to strings. (writestr functions like write/writestr but then to an string. Originally implemented for ISO/Mac dialects)

Upvotes: 7

Related Questions