Link to home
Start Free TrialLog in
Avatar of RoelPotman
RoelPotman

asked on

Writing a textfile with fixed postions

(I have no idea how hard the question is, so I choosed moderate)

I have information; alphabetic,  numeric or alphanumeric, I want to create  a textfile with fixed positions for the fields. I looked for it
 everywhere and sometimes I see a simular question, but never an answer, but  I can not imagine it is not possible.
 
 For example
 Position 1-3,      length 3  Currency code
 Position 4-21,       length 17 numeric value of which 6 figures before the point
                   and 10 after, but the point has a fixed position.
 Position 22-29,      length 8   date   format eejjmmdd
 
 Example of the suggested outputfile:
123     1234567890123456712345678
 EUR             2.20371             19990531
 ITL                 0.00000004     19990531
 XXX          123.654321          19990531
 
 I tried with the WRITELN([var f: text;] p1[,p2, ,Pn]) ,but this is no  success, I realise the P1 is the width.
 
 I am looking for the general way to solve this question in future in Delphi and/or Pascal.
If you do not have a example, can you give me a hint how to solve this and/or which keword I have to use for finding
something like this (to build on further).

 
 Thanks in advance for any reaction,
 Roel Potman
 
 PS
 If I can help by sending you a program that reads a text file with a  textfile to read, I will do this with pleasure.
Avatar of RoelPotman
RoelPotman

ASKER

Edited text of question.
there is some ":5" you can put in your writeln procedures to determine the field size.
the 5 is for a fiels of size 5 characters,
You could also write your own little function that would truncate or expand strings to be the size you want them to be.

Convert a value that needs to be writed to a string. Pass it through your function. Your function would pad with spaces or truncate the incoming string. You would write the outcoming string to the textfile.

My two cents worth,
Bob
In BASIC, it's PRINT USING. I don't recall exactly in Pascal, but there's gotta be a similar function, and that depends on which variant you're using.
ASKER CERTIFIED SOLUTION
Avatar of Triskelion
Triskelion
Flag of United States of America image

Link to home
membership
This solution is only available to members.
To access this solution, you must be a member of Experts Exchange.
Start Free Trial
Triskelion's solution would be good, but not as a text file.
But if you write a binary file WITH all the CR/LF and use only ASCII characters, the result is exactly the same.

A "work around" would be create strings of the length required (TP had a SPACE command, I think), then fit your string INTO this "template", and write this template out as needed, and repeat for every field and record.
Programmers thanks,

I will first practice the solution of Triskelion.
I am enthousiastic, but I do not want to close my question without be sure.

Some additional Information:
Turbo Pascal &.0 or Delphi v3.0

KSCHANG: I also thought of a simular function of PRINT USING, but I did not found it.

BSoeters building a function: Itried but did not succeed until now.

Triskelion,

Is is possible to get in touch which you directly to exchange information ?

Thanks,
Roel 101515.1131@compuserve.com
{try this one for strictly text files}
var
   hOutFile     : TEXT;
   sCurrencyCode: String;
   fLargeFloat  : REAL;
   sDate        : String;

begin
   assign(hOutFile,'Test.Dat');
   rewrite(hOutFile);
   sCurrencyCode := 'EUR';
   fLargeFloat   := 111111.1234567890;
   sDate         := '19990707';
   write(hOutFile, sCurrencyCode:3, fLargeFloat:6:10, sDate:8);
   close(hOutFile);
end.
By the way... the REAL has a floating precision of 5.
111111.12345657890 rounded to 111111.123460000
as you see -  Triskelion uses the idea I 've suggested uding the ":A" (where A is an integer number) in order to explicitlly say  which filed length is required for the print.

the format VARIABLE:C:D on a "write()" command means that the variable "VARIABLE" will be written in a text  fiels C characters long and with D characters after the decimal point.

Baruche is right, though not entirely.

The width and precision specifiers will only denote the MINIMUM field size. Not the maximum !!

There's another problem with the described method: the decimal point is not in a fixed position.
Right, but it should do.
even in C it's done like that (using %7d, for example, for a 7 character long field for an int variable).

Shlomoy, right.

But even in C, it denotes just the minimum size, not the maximum. To be certain that the same information is always in the same place, you'd need some function to specify the maximum output.
BSoeters, I guess...
Anyway - I think that RoelPotman got all the answers he needs regarding his problem. :-)
In Pascal, the write command does only tell what is the minimum.
In C, you can denote also what is the maximum.
{Out of language example given below}
#include <stdio.h>
void main(void)
{
      char sData[100];
      sprintf(sData, "There once was a man from Murfreesboro");
      printf("%10s", sData);
      /*
      prints:
      There once was a man from Murfreesboro
      */
      printf("%10.10s", sData);
      /*
      prints:
      There once
      */
}
Programmers,

The speed and number of reactions impress me! Thanks!

Regarding :-), but it is not gonna be easier for me. Especially I am not an original programmer and certainly not a C-programmer.

So I think it is better that I attach my example/ exercise code, so we talk all about the same.

I did not use this site before, even did not no the moderate, but I think
afterwards I had attached the code immediately.

By the way any comment on how to program these things efficiently are welcome ! Thanks in advance. Roel


PROGRAM quest;
USES
  Crt;

textin, example:
British Pound  GBPUNITED KINGDOM        123456.123456789019990701

In this case I read text and I write the same text through,
What if I have numeric values of different length and I want to write them with the decimal point on same position in a file ?

TYPE
  infrec = RECORD
             CURDESC : STRING[15];
             ISOCODE : STRING[3];
             Country : STRING[21];
             Curval : STRING[17];
             Dat : STRING[8];
           END;
VAR
  r : infrec;
  i : Byte;
  infile, outfile : text;
  hs : STRING;
  rs : Real;
  res : Integer;

BEGIN
  ClrScr;
  Assign(infile, 'c:\vraag\textin.txt');
  Reset(infile);
  Assign(outfile, 'c:\vraag\textout.txt');
  Rewrite(outfile);
  r.CURDESC := '';
  r.ISOCODE := '';
  r.Country := '';
  r.Curval := '';
  r.Dat := '';

  WHILE NOT EoF(infile)
  DO BEGIN
       Readln(infile, hs);
       FOR i := 1 TO 3
       DO r.ISOCODE := r.ISOCODE + hs[i + 15];
       FOR i := 1 TO 17
       DO BEGIN
            r.Curval := r.Curval + hs[i + 40];
            Val(r.Curval, rs, res);
            res := res + 3211;
          END;
       FOR i := 1 TO 8
       DO BEGIN
            r.Dat := r.Dat + hs[i + 57];
            Val(r.Dat, rs, res);
          END;

   {  Writeln(outfile,r.dat:4);            { write 8 positions !!! }
   {  Writeln(outfile,r.curval:17:5)       { error 89 ")" }
       Writeln(outfile, r.ISOCODE, r.Curval, ' ', r.Dat:2, ' ', rs:8); { This is text->text, how number ->  }

       r.CURDESC := '';
       r.ISOCODE := '';
       r.Country := '';
       r.Curval := '';
       r.Dat := '';
     END;
  Close(infile);
  Close(outfile);
END.
 

You need to separate the two techniques.
If you are going to use the size parameters, then remove the RECORD.

If you are going to use the RECORD, remove the size parameters.  The RECORD takes care of the size and placement issue.

Also, if you use STRING in the RECORD, be sure you also read STRING when pulling the data back in.  The STRING in Pascal is a structure of sorts.  The first byte STRING[0] is the length parameter.  I used array[1..n] of char to allow you to view the output file with a text editor.
{something like this}
PROGRAM quest;
USES    Crt;

TYPE
   infrec = RECORD
      CURDESC : array [1..15] of char;
      ISOCODE : array [1..3 ] of char;
      Country : array [1..22] of char;
      Curval  : array [1..17] of char;
      Dat     : array [1..8 ] of char;
      CRLF    : array [1..2 ] of char;{carriage return/line feed}
   END;

VAR
   r       : infrec;
   infile,
   outfile : file of infrec;
   iLoop   : integer;

BEGIN
   ClrScr;
   Assign(infile, 'textin.txt');
   Reset(infile);
   Assign(outfile, 'textout.txt');
   Rewrite(outfile);
   {for iLoop := 1 to 3 do}
   while(not eof(infile)) do
      BEGIN
      {$I-}
         read(infile, r);
      {$I+}
         if IoResult = 0 then Write(outfile,r);
      END;
  close(outfile);
  close(infile);
end.
Did you get it fixed?
I sent Triskelion, straight an reaction. So I wait for his reaction After this I will close the question.
Looks good.  It'll work.