Tek-Tips is the largest IT community on the Internet today!

Members share and learn making Tek-Tips Forums the best source of peer-reviewed technical information on the Internet!

  • Congratulations strongm on being selected by the Tek-Tips community for having the most helpful posts in the forums last week. Way to Go!

Variable numer of columns

Status
Not open for further replies.

pi3cho

Programmer
Oct 18, 2010
10
PL
It's me again
I found a program which writes 100 columns with numbers.Now i would like to do the same but write columns with leters like A,B,C

PROGRAM tst
IMPLICIT NONE

INTEGER i,imxcol
CHARACTER varfmt*13

imxcol=99
varfmt='(XXX(E20.10))' !i've tried to change E20.10 on A10
WRITE(varfmt(2:4),FMT='(I3.3)')imxcol !and I3.3 on A10 but nothing works

OPEN(UNIT=1,FILE='tst.txt',STATUS='UNKNOWN')
WRITE(1,FMT=varfmt)(i*1.,i=1,imxcol,1)
CLOSE(1,STATUS='KEEP')

END

I still don't have a solution.Any help?
Thank you all

 
Use write(*,*)varfmt to see what you are doing. The original programmer was changing the places of XXX in the string (position 2 to 4 (2:4)) to make it for a variable number of columns

E20.10 is for reals in scientific notation. Change it to I10.10 for example and see what happens

A reasonable complete description for the options you have:
Code:
Format descriptor:

Iw[.m]      Integer values
Bw[.m]      Binary values
Ow[.m]      Octal values
Zw[.m]      Hexadecimal values
Fw.d        Real values
Ew.d[Ee]    Real values with exponents 
ENw.d[Ee]   Real values in engineering notation
ESw.d[Ee]   Real values in scientific notation
Gw.d[Ee]    Real values, extended range 
Dw.d        Double-precision real values
Lw          Logical values
A[w]        Character values

In this column, w represents width of field,m represents number of leading zeros,d represents number of digits following the decimal point, and e represents the exponent.
The following table shows nonrepeatable edit descriptors.
 
Hi all,
and thanks for preview help but another problem occured.I've wrote a code which looks like this:

program vol_aqua
implicit none
real::,lenght,width,height,volume
OPEN (1,FILE='data01.dat',status='old')
read(1,*) height
read(1,*) lenght
read(1,*) width
volume=(height*lenght*width)/1000
open(8,file='obj.txt',status='unknown')
write(8,*) "volume is",volume
close(8)
write (*,*) "volume is",volume
end program vol_aqua

File 'data01.dat' contains data as follows:
height 100.0
lenght 80.0
width 40.0

After compiling there is this error:
"At line 5 file of file vol_aqua.f90 <unit=1, file='data01.dat'> Fortran runtime error: bad real number in item 1 of list input"
I've made several changes in the code like replacing REAL for INTEGER,100.0 for 100 or data01.dat for data01.csv. Nothing works.
How to solve this problem? Thanks for help.
Cheers
 
Sorry but i don't get it."Height" is not a real numer and "volume,width,lenght" are?
If "height" is not a real number then should it be integer (?) - but if so should't words "width,lenght" be integer also and word "volume" real?
I'm confused.
 
No, I mean the WORD height in your text file data01.dat, the the variable in your code.

Your are reading the REAL variable height and Fortran expects to be able to read a number as the first variable. Instead, it finds a written word "height"

Take away those words in your files or put them behind the number instead of in front of them
 
Ok:)now i know what you meant but i've done it before and there was the same problem.
Now data file looks like this:

100.0 height
80.0 lenght
40.0 width

and it doesn't help.
Maybe the problem is due to a file itself because first i'm creating 'data01' as an excel file and just then i'm saving it as a 'data01.dat'.That's the only thing that comes to my mind:/
 
Finally
I've changed the variables like this
100.0
80.0
40.0
height
lenght
width
and it works.Uff
Thanks a lot for help
 
Now i'm thinking that there's got to be a way to read variables even when data file (data.csv) looks like this

height 100.0
lenght 80.0
width 90.0

How to read only numbers?
 
program vol_aqua
implicit none
real:: length,width,height,volume
character(8) :: name

open (1,FILE='data01.dat',status='old')

read(1,*) name,height
read(1,*) name,length
read(1,*) name,width
...
end program
 
It doesn't work.When code looks like this:

program vol_aqua
implicit none
real::height,lenght,width,volume
character (8) :: name
OPEN (1,FILE='data01.csv',status='old')
read(1,*) name,height
read(1,*) name,lenght
read(1,*) name,width
volume=(height*lenght*width)/1000
open(8,file='vol.txt',status='unknown')
write(8,*) "volume is",volume
close(8)
write (*,*) "volume is",volume
end program vol_aqua

I still get the answer: Bad real number in item 2 of list input:(
 
what is your FORTRAN compiler ? Indeed, the solution I proposed needs a F95 compiler. With F77, the strings in the data file needed to be surrounded by apostrophes. This is no more necessary with F95.

I have tested the program with the compilers ifort (Intel) and gfortran (GCC) with the following data file data01.csv :

Code:
height 100.0
length 80.0
width 90.0

The program is :

Code:
program vol_aqua
  implicit none
  real:: length,width,height,volume
  character(8) :: name

  open (1,FILE='data01.csv',status='old')

  read(1,*) name,height
  read(1,*) name,length
  read(1,*) name,width
  write(*,*) height,length,width
end program

And the result :

Code:
$ ifort vol_aqua.f90
$ ./a.out
   100.0000       80.00000       90.00000
 
Hmm..
My fortran comipler is gfortran so it should work.I've made some changes to the code:

program vol_aqua
implicit none
real:: length,width,height,volume
character(8) :: name

open (1,FILE='data02.txt',status='old')

read(1,'(A10,F10.2)') name,height
read(1,'(A10,F10.2)') name,length
read(1,'(A10,F10.2)') name,width
write(*,*) height,length,width
end program

and in result i'm getting this:
0.00000 0.00000 0.00000.
And still i don't know what's the problem:/
 
check the format of your input file

The fact that FJaq's solution works seems an exception rather than a rule to me (if I understood it well).

His variable "name" is character(8) so when he reads READ(1,*)name,width for example, name should contain "width 90" i.e., the first 8 characters on the line, while width contains the real value of ".000" character 9 to 12 for example.

There are 2 solutions to this. You either write your file in fixed format
input file:
Code:
123456789012345678901234567890
<-name-><-number--------------
or you read a whole line at once containing both and separate them afterwards. For example:
Character(25) :: line
Then line will contain:
"width 90.000 "
for example after having read the third line
It's upto the programmer then to separate the stuff from the read line.
So:
ispace=INDEX(line,' ') will give the value 6
Next, you read in the line
READ(line(1:ispace-1),'(A8)')name
READ(line(ispace:25),*)width

Of course it's easier to read with a fixed format, but your input file has to fullfil this fixed format as well.
 
The fact that FJaq's solution works seems an exception rather than a rule to me (if I understood it well).

No this is the RULE !

In particular, the length of the character string I used does not matter : any length will give the same answer.

The use of the free format * is important if the strings in the data file have not all the same length. Indeed, the free format works with the space as delimiter.

In comparison, the test program of pi3cho does not work because the fixed format A10 expects exactly 10 characters. As the names are not occupying 10 characters exactly, the numbers a read badly. For instance, the first line is read as follows :
- first field : "height 100"
- second field : ".0"

Notice that the second field is truncated because the format expected a number on 10 characters (F10.2). I don't remember the rules about truncated fields... A simple advice : avoid that !

Example of my program with another string length (=1) :

Code:
program vol_aqua
  implicit none
  real:: length,width,height,volume
  character :: name

  open (1,FILE='data01.csv',status='old')

  read(1,*) name,height
  read(1,*) name,length
  read(1,*) name,width
  write(*,*) height,length,width
end program

Of course, another way would be to read each line in a long character variable (with the format '(A)'), to scan that variable, locate fields, compute the lengths of the fields and read them from the variable itself. But why trying something complicated when a simple format * is perfect in that case ?
 
Apart from not noticing the * in your format, I didn't know this, I thought this only worked for numbers.

Thanks!

I remember some codes where I have been complicating myself reading lines of length 80 and then looking for the delimiter.

Does it work with tabs as delimiter as well?
 
Does it work with tabs as delimiter as well?

Yes and with comma too !

The only thing I don't remember is whether this feature comes from FORTRAN-90, FORTRAN-95 or FORTRAN-2003.

But it works with all the compilers I use : gcc (gfortran), g95, intel (ifort), nag, sun.
 
Status
Not open for further replies.

Part and Inventory Search

Sponsor

Back
Top