Board index » delphi » Q: Strings and Printers and Such (Problems printing directly to printer)

Q: Strings and Printers and Such (Problems printing directly to printer)

Quote
Jim Burns <jimbu...@phoenix.net> wrote:

> 1:  Strings.  Is there a way to identify the end of the
> string.  Like '\0' in a C style array?  I think I'm running
> into problems, not accessing indexes directly, but when I
> print strings of say string[80] but I've only used the
> first 50 chars what identifies the end of my 50 char
> string?

You can use the function Length(S) which will return the length
of the string. It utilizes the fact that the length of the string
is stored in the first byte. But beware in Delphi 32 all strings
are going to be dynamically created.

Quote

> I realize the indexing runs from 1 to length and I've been
> able to verify a particular string that I do use and index
> on and it works as expected.  But I'm indexing directly
> and never printing the string as a whole.  In fact it is
> declared as string[4] but may only have 2 characters
> stored in it.... and I'm using Length(identifier) to
> find the lenght and it's been correct so far.  But I read
> somewhere, or got the impression anyway that changing the
> [0] index might not be the best way to constrain the length
> of the string.  Is it simply ok to say set String[0]:=50 in
> my example above?

Given that why not construct statements like :
for i :=  1 to Length(S) do
  Writeln(S[i]);

Or if what you are wanting is the ability to trim whitespace then
write or locate your own trim function (trims whitespace).

As far as direct output to printer in BP7 you could do something
like this

var
 Device : Text;

begin
  Assign(Device, LPT1);
  Reset(Device);
  Writeln(Device, 'Hello World');
  Close(Device);
end;

I know that Assign has been replace by AssignFile, Text by TextFile
ect in Delphi but the idea should be the same.

 

Re:Q: Strings and Printers and Such (Problems printing directly to printer)


For the record I am living off the Delphi manuals at this
point and I must say they are extremely difficult to glean
good infomation from.  I certainly plan on hitting the
bookstore soon.

In the interim, I'm just working on my first Delphi
utility.  It's not very glorious, but it has given my
Delphi mind a workout.  It's a small utility to generate
pages of simple math problems for my 5 yr. old.  Eek, I
hate having to think up 36 math problems by hand... so....

I've gotten everything working, but getting the generated
problems to print correctly.  I must admit that I don't
completely understand strings and char arrays in pascal,
and this sure makes printing them extremely difficult.  Be
assured I have played with this for hours and I've tried
almost every possible combinations and options I've been
able to concieve.  But I do have a couple of questions I'd
like to pose to anyone who can advise.

1:  Strings.  Is there a way to identify the end of the
string.  Like '\0' in a C style array?  I think I'm running
into problems, not accessing indexes directly, but when I
print strings of say string[80] but I've only used the
first 50 chars what identifies the end of my 50 char
string?

I realize the indexing runs from 1 to length and I've been
able to verify a particular string that I do use and index
on and it works as expected.  But I'm indexing directly
and never printing the string as a whole.  In fact it is
declared as string[4] but may only have 2 characters
stored in it.... and I'm using Length(identifier) to
find the lenght and it's been correct so far.  But I read
somewhere, or got the impression anyway that changing the
[0] index might not be the best way to constrain the length
of the string.  Is it simply ok to say set String[0]:=50 in
my example above?

2:  I just do not understand printing output.  I've been up
and down the TPrinter and TCanvas online documentation and
here is what I've come up with.

  Printer.Canvas.TextOut(0, LineCount, Line1Out);
  LineCount := LineCount + 1;
  Printer.Canvas.TextOut(0, LineCount, Line2Out);
  LineCount := LineCount + 1;
  {Printer.Canvas.TextOut(0, LineCount, Line3Out);}
  LineCount := LineCount + 4;

What I'm doing is generating randomly 4 problems and then
printing them across the page like for example:

   3       5       10     23
  -2      +2      + 5    -12
  ---     ---     ---    ---

If I remember correctly from pascal, I used to do something
like:

  var
    Printer: Text;

  begin

    writeln(Printer, "Hello");  

But this does not seem to work... so I hit upon using
TextOut.  The way I figure it  I do all the "painting" on
the canvas before the   Printer.EndDoc;  but I am still
insuring that I print linearly to the printer.  I don't
know if you can print on row 24 then to row 5 and have
things turn out correctly.  One might expect you could
since the impression of the canvas would seem to work that
way.  But, either way... the X, Y parameters in the TextOut
call seem to have no effect.  I've made them constants...
no brainers like 0,0 and then 5,5... but the only line that
prints is the last call to TextOut.  And it prints clear..
there is no layering of print.

Now there sure may be a better way to do this but to build
the LineXOut I'm simply doing it like:

   Line1Out := '   ' + IntToStr(Operand1A) + '    ' +
                       IntToStr(Operand1B) + '    ' +
                       IntToStr(Operand1C) + '    ' +
                       IntToStr(Operand1D);

I did try:

   Line2Out := Format('%s %d   %s %d   %s %d   %s %d',
               [OperatorString[OperatorA], Operand2A,
                OperatorString[OperatorB], Operand2B,
                OperatorString[OperatorC], Operand2C,
                OperatorString[OperatorD], Operand2D]);

but I kept getting strange scratches at the end and above
the printed string.

My biggest concern is why do successive calls to TextOut
with different strings with different X,Y coordinates only
print the last call?

I've always found printing formatted strings directly to
the print to be a real pain in my side.  I realize this may
be a lot to cover, but ANY insights are greatly
appreciated... and may just save the rest of my hair!!

TIA,

--

-- Jim Burns
   Technology Dynamics
   Pearland, Texas

Re:Q: Strings and Printers and Such (Problems printing directly to printer)


Quote
Jim Burns (jimbu...@phoenix.net) wrote:

: 1:  Strings.  Is there a way to identify the end of the
: string.  Like '\0' in a C style array?  I think I'm running
: into problems, not accessing indexes directly, but when I
: print strings of say string[80] but I've only used the
: first 50 chars what identifies the end of my 50 char
: string?
Element 0 is the length byte.  The Length(string) functions returns
this value.

: I realize the indexing runs from 1 to length and I've been
: able to verify a particular string that I do use and index
: on and it works as expected.  But I'm indexing directly
: and never printing the string as a whole.  In fact it is
: declared as string[4] but may only have 2 characters
: stored in it.... and I'm using Length(identifier) to
: find the lenght and it's been correct so far.  But I read
: somewhere, or got the impression anyway that changing the
: [0] index might not be the best way to constrain the length
: of the string.  Is it simply ok to say set String[0]:=50 in
: my example above?
Yes.  The "proper" method would be string := Copy(String,1,50);
but String[0]:=50; is much more effecient, though maybe not as proper.

--

   _/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/
  _/ Derek B. Snider     de...@idirect.com    _/ telnet://realms.game.org:4000
  _/ Senior Programmer / System Administrator _/ telnet://telecafe.com:9000
  _/ ComputerLink Online Inc.                 _/ http://www.idirect.com
  _/ 5150 Dundas St. W. Suite #306            _/ http://pizza.idirect.com
  _/ Etobicoke, ON, M9A 1C3, Canada           _/ http://www.game.org
  _/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/
 ---------------------------------------------------------------------
 : Internet Direct.                    Realms of Despair!            :
 : (416)233-2999, 359 lines            telnet realms.game.org 4000   :
 : T1 bandwidth, 300-28,800 bps        Endless medieval enjoyment!   :
 :                                                                   :
 : Stop by for a drink at the Internet TeleCafe -- telecafe.com 9000 :
 ---------------------------------------------------------------------

Re:Q: Strings and Printers and Such (Problems printing directly to printer)


Quote
Jim Burns (jimbu...@phoenix.net) wrote:

: 2:  I just do not understand printing output.  I've been up
: and down the TPrinter and TCanvas online documentation and
: here is what I've come up with.

:   Printer.Canvas.TextOut(0, LineCount, Line1Out);
:   LineCount := LineCount + 1;
:   Printer.Canvas.TextOut(0, LineCount, Line2Out);
:   LineCount := LineCount + 1;
:   {Printer.Canvas.TextOut(0, LineCount, Line3Out);}
:   LineCount := LineCount + 4;

: My biggest concern is why do successive calls to TextOut
: with different strings with different X,Y coordinates only
: print the last call?

I believe there are two things which combine to create the behavior
you see.  First, the X,Y parameters to TextOut are measured in
pixels by default.  That means that you're only moving each line
down by a printer dot or four.  The other contributor is that
the text is probably printing with a solid white background which
erases previous text underneath.

The solution would be to use the TextHeight (I think) method of
the printer canvas to ask how tall the text is, and multiply your
Y coordinate (LineCount) by this TextHeight value.

You might also consider drawing this stuff to the screen for
debugging until you get things looking right.  Screen canvases
work almost exactly like the printer canvas, and they don't use
up so much paper.  Just drop a Paint object on a form and start
drawing onto its canvas.

Good luck.

-- Mike Salisbury

Re:Q: Strings and Printers and Such (Problems printing directly to printer)


On Thu, 09 Nov 1995 01:01:46 GMT, ma...@weblifepro.com (Mark Terrano)
wrote:

Quote
>>Yes.  The "proper" method would be string := Copy(String,1,50);
>>but String[0]:=50; is much more effecient, though maybe not as proper.

>From what I understand about Delphi32 - this will no longer be possible (since you will be able to access very large
>strings - i.e. more than 1 byte reference).   Stick with the Length() or Copy() functions to be on the safe side.

According to Borland's web pages, Delphi32 will have two new procedure
(among other new things):

SetLength(var Str: string; Length: Integer);
SetString(var Str: string; Source: PChar; Length: Integer);

To enhance portability, I suggest implementing these functions in
Delphi 1.0. Then use SetLength whenever you need to set the length of
a string, and you can upgrade your code to Delphi 32 painlessly.
(Unless, of course, Borland decides to do something different from
what they have posted...)

---------------------------------------------------
unit Strings;

{ Delphi 1.0/Delphi32 string compatibility unit. Delphi32 has long
  strings, and uses the SetLength and SetString functions to
  manipulate them. Delphi 1.0 lacks these functions. For portability,
  this unit defines these procedures appropriately for Delphi 1.0.

  Tempest Software
  10 November 1995

Quote
}

interface
{$ifndef WIN32}
type
  ShortString = string;

procedure SetLength(var Str: string; Length: Byte);
procedure SetString(var Str: string; From: PChar; Length: Byte);
{$endif}

implementation

{$ifndef WIN32}
uses SysUtils;

procedure SetLength(var Str: string; Length: Byte);
begin
  Str[0] := Chr(Length)
end;

procedure SetString(var Str: string; From: PChar; Length: Byte);
begin
  Str[0] := Chr(Length);
  Move(From^, Str[1], Length);
end;

{$endif}
end.
--
Ray Lischner         (li...@tempest-sw.com)
Tempest Software, Corvallis, Oregon, USA

Other Threads