Jump to content
Martin Liddle

Is there a Delphi equivalent of WriteStr ?

Recommended Posts

I am porting some code from the Gnu Pascal compiler that makes extensive use of WriteStr which is an ISO 10206 Extended Pascal extension; is there a Delphi equivalent?   For those not familiar with WriteStr, WriteStr(S,Args) behaves like Write, except that it stores its output in the string variable S instead of a file. 

Edited by Martin Liddle

Share this post


Link to post
9 hours ago, uligerhardt said:

That should be just Str.

Str just converts number to string.... As David Schwartz writes, format is functionally similar, but it has different syntax (format is more like C printf than Pascal Write).  But unlike fpc Delphi does not seem to have WriteStr.

Share this post


Link to post
33 minutes ago, Sherlock said:

Hmm almost sounds like a job for TWriter.WriteString which writes to a TStream. If you don't want it to be a file, it could be a TStringStream.

No it is not. TWriter.WriteString writes strings.

example:
 

program writeStrTest;
{$mode objfpc}
{$H+}
var
  x: extended;
  y: Int64;
  s, s2: string;
begin
  x := 193.17;
  y := 123746214;
  s := 'Some tekst';
  WriteStr(s2, 'x = ', x:10:4, ', y = ', y:10, ', s = ', s:20);
  WriteLn(s2);
end.

will output

x =   193.1700, y =  123746214, s =           Some tekst

 

format is closest thing in Delphi, but format does not have ability to pad values with spaces (if user requires it).

 

 

Share this post


Link to post

UliGerhardt's solution could be wrapped - but it would be challenging to make threadsafe.

 

It would treat s2 like a file, and write to the file.

With a helper class, it would be possible to read the last written content out from s2 as a String again.

 

Is it unthinkable to simply replace

WriteStr(s2,
with

Writeln(

?

Share this post


Link to post
36 minutes ago, Virgo said:

but format does not have ability to pad values with spaces

it has: `%10d`

 

You can borrow the code from GNU Pascal but you'll have to wrap arguments into array. Delphi doesn't support user functions with undefined number of arguments

Edited by Fr0sT.Brutal

Share this post


Link to post
7 minutes ago, Lars Fosdal said:

Is it unthinkable to simply replace

WriteStr(s2,
with

Writeln(

?

That only applies, if goal is to write to file or stdout. My example code did writeln to result string just to get, what the value was. Real use can be different. But depending, what WriteStr features were used it should be possible to rewrite it in Delphi.

Share this post


Link to post

I see. How many of these do you need to replace?

If it is not a massive number, I would go for Format

It can both left and right pad with spaces if so is required, but converting the WriteStr formats will be a chore.

 

WriteStr(s2, 'x = ', x:10:4, ', y = ', y:10, ', s = ', s:20);
s2 := Format('x = %10.4f, y = %10d, s = %-20s, [x, y, s]);

The usual f'up here is to either missalign the format string and the number of params, or have the wrong type variable in relation to the format specifier.

Share this post


Link to post
11 minutes ago, Fr0sT.Brutal said:

it has: `%10d`

 

I somehow managed to miss width parameter. With it it is really possible to rewrite WriteStr as format and since Delphi does not have WriteStr, it is best solution. Better than trying to hack around with file.

So:

s2 := format('x = %10.4f, y = %10d, s = %20s', [x, y, s]);

would be same as

WriteStr(s2, 'x = ', x:10:4, ', y = ', y:10, ', s = ', s:20);

 

Edited by Virgo

Share this post


Link to post
20 hours ago, Martin Liddle said:

I am porting some code from the Gnu Pascal compiler that makes extensive use of WriteStr which is an ISO 10206 Extended Pascal extension; is there a Delphi equivalent?   For those not familiar with WriteStr, WriteStr(S,Args) behaves like Write, except that it stores its output in the string variable S instead of a file. 

It used to be possible to kind of redirect the output of Write/WriteLn using something called a "text-file device driver". I found some ancient unit of mine in the newsgroup archives, see https://codenewsfast.com/cnf/article/0/permalink.art-ng1618q5913 . If the link does not work search for "Unit StreamIO". It contains a AssignStream procedure you can use to attach a stream (in this case a TStringstream would be appropriate) to a Textfile variable. Output to this variable would then end up in the stream, from which you can get the content as a string.

 

As I said this is old code, I have no idea how it behaves under Unicode-enabled versions of Delphi.

Share this post


Link to post
36 minutes ago, PeterBelow said:

It used to be possible to kind of redirect the output of Write/WriteLn using something called a "text-file device driver".

That's the core of Uwe's code I linked to.

Share this post


Link to post

Peter: that generally still works as of Delphi Seattle, I use it regularly. But it might have unicode issues due to working over a pansichar buffer, which would cause corruption when unicodestring is converted to array of ansichar. There is some MBCS support in textrec too but I have no experience with it, and probably would require updating devin/out.

 

As so often, a workaround for that could be  setting the ansi codepage to UTF-8 per Windows 10-1805+ manifest, but that of course has very wide consequences. I don't have much experience with that in Delphi.

 

Free Pascal has an unit of the same name and fucntion, but also supportsWriteStr(), which is available even in Delphi mode, so it is first order approx compatible with both Delphi and GPC for this.

Share this post


Link to post

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!

Register a new account

Sign in

Already have an account? Sign in here.

Sign In Now

×