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.
RoelPotmanAsked:
Who is Participating?
I wear a lot of hats...

"The solutions and answers provided on Experts Exchange have been extremely helpful to me over the last few years. I wear a lot of hats - Developer, Database Administrator, Help Desk, etc., so I know a lot of things but not a lot about one thing. Experts Exchange gives me answers from people who do know a lot about one thing, in a easy to use platform." -Todd S.

RoelPotmanAuthor Commented:
Edited text of question.
0
shlomoyCommented:
there is some ":5" you can put in your writeln procedures to determine the field size.
0
shlomoyCommented:
the 5 is for a fiels of size 5 characters,
0
Cloud Class® Course: Amazon Web Services - Basic

Are you thinking about creating an Amazon Web Services account for your business? Not sure where to start? In this course you’ll get an overview of the history of AWS and take a tour of their user interface.

BSoetersCommented:
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
0
kschangCommented:
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.
0
TriskelionCommented:
{
Try something like this.  It makes life much simpler when you use a structure (record).  You can convert the number back and forth from float to character array when necessary.
}
type
   MY_REC = record
      sCurrencyCode : array[1..3]  of char;
      sLargeFloat   : array[1..17] of char;
      sDate         : array[1..8]  of char;
   end;

var
   xTestRec : MY_REC;
   hOutFile  : file of MY_REC;

begin
   assign(hOutFile,'Test.Dat');
   rewrite(hOutFile);
   xTestRec.sCurrencyCode := 'EUR';
   xTestRec.sLargeFloat   := '111111.1234567890'; {convert this to float after retrieval}
   xTestRec.sDate         := '19990707';
   write(hOutFile, xTestRec);
   close(hOutFile);
end.
0

Experts Exchange Solution brought to you by

Your issues matter to us.

Facing a tech roadblock? Get the help and guidance you need from experienced professionals who care. Ask your question anytime, anywhere, with no hassle.

Start your 7-day free trial
shlomoyCommented:
Triskelion's solution would be good, but not as a text file.
0
kschangCommented:
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.
0
RoelPotmanAuthor Commented:
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.

0
RoelPotmanAuthor Commented:
Triskelion,

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

Thanks,
Roel 101515.1131@compuserve.com
0
TriskelionCommented:
{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.
0
TriskelionCommented:
By the way... the REAL has a floating precision of 5.
111111.12345657890 rounded to 111111.123460000
0
barucheCommented:
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.

0
BSoetersCommented:
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.
0
shlomoyCommented:
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).

0
BSoetersCommented:
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.
0
shlomoyCommented:
BSoeters, I guess...
Anyway - I think that RoelPotman got all the answers he needs regarding his problem. :-)
0
TriskelionCommented:
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
      */
}
0
RoelPotmanAuthor Commented:
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.
 

0
TriskelionCommented:
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.
0
TriskelionCommented:
{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.
0
TriskelionCommented:
Did you get it fixed?
0
RoelPotmanAuthor Commented:
I sent Triskelion, straight an reaction. So I wait for his reaction After this I will close the question.
0
TriskelionCommented:
Looks good.  It'll work.
0
It's more than this solution.Get answers and train to solve all your tech problems - anytime, anywhere.Try it for free Edge Out The Competitionfor your dream job with proven skills and certifications.Get started today Stand Outas the employee with proven skills.Start learning today for free Move Your Career Forwardwith certification training in the latest technologies.Start your trial today
Pascal

From novice to tech pro — start learning today.