I am using fortran and in my program I am reading a .CSV file which cuts off leading and trailing zeros. I need to turn the number with 2 decimal places into an I8.8 integer?

Also, by "number with 2 decimal places", provide an example. Do you mean a number wityh 2 digits (e.g. 37) or do you mean a number with a fractional component, like 37.02 ?

1234.5678,666,1,0,55

Why should this format "cut off leading and trailing zeros"? Is your programme reading such files, or producing them?

Using fortran, you could read such data using the free format option, thus:

READ(IN,*) ARRAY

where ARRAY is indeed an array, of some size or other. If ARRAY is a floating-point type variable, then all numbers, integer or not, will be suitable for input. The main problem is, how many numbers are to be read in? Each line of input has the same count of numbers, or, some count that is knowable? Or, is perhaps the first number the count of numbers to follow? In this (useful and flexible case) case,

READ (IN,*) N,(A(I),I = 1,N)

would do the trick.

What do you mean by I8.8? That is not a valid format code. Do you mean F8.8? Or what? If something has decimal places, it is not an integer. If you wish, you could rescale the numbers: read them into ARRAY as floating-point (with any fractional parts acceptable, then transfer the numbers to an integer array, thus:

IARRAY = ARRAY*100

or, if N were known to have been read,

IARRAY(1:N) = ARRAY(1:N)*100

Amusingly enough, I have been confronting .csv data, and the following code segment might help. Following an EATINT is EATREAL, as follows:

LOGICAL FUNCTION EATREAL(V) !This is even worse.[than EATINT]

Chews into the likes of 666, -666.666, and 666.666E666 (=666.666*10**666)

Completes with the value in V, success as the result, and L1 and L2 advanced.

Concocted by R.N.McLwean (whom God preserve) May XXMM.

REAL*8 V,X,POW,TENS !Maximum precision for all this fun.

INTEGER*2 D,DD,P !Digit counting and such.

LOGICAL ADIGIT,XNEG,PNEG !Things noticed along the way.

REAL*8 TEN(0:8) !A small table, only.

DATA TEN/1,10,100,1000,10000,10

CHARACTER*30 BURP !In case of trace.

INTEGER*2 I Am !Self-identification.

CALL $SUBIN("EatReal",I Am) !Hello there.

ADIGIT = .FALSE. !No digits seen.

PNEG = .FALSE. !No negative exponent.

XNEG = .FALSE. !No negative number.

DD = 0 !No decimal digits.

P = 0 !No exponent.

X = 0 !No value.

L2 = L1 !The starting point.

IF (L2.GT.LA) GO TO 40 !Urk! Off the end even before I start.

Chew into the number. Admit a possible leading sign, then digits.

IF (ACARD(L2:L2).EQ."+") GO TO 1 !Well, first consider

IF (ACARD(L2:L2).NE."-") GO TO 2 !Possible signs.

XNEG = .TRUE. !To be acted upon later.

1 L2 = L2 + 1 !Advance one.

2 IF (L2 .GT. LA) GO TO 30 !Off the end?

D = ICHAR(ACARD(L2:L2)) - ICHAR("0") !Taste the candidate digit.

IF (D < 0 .OR. 9 < D) GO TO 10 !Is it to my taste?

X = X*10 + D !Yes. Yum.

ADIGIT = .TRUE. !A digit has been seen.

GO TO 1 !More might well follow.

Consider any decimal digits, those following a .

10 IF (ACARD(L2:L2).NE.".") GO TO 20 !Any sign?

11 L2 = L2 + 1 !Yes. Advance one.

IF (L2.GT.LA) GO TO 30 !Sudden end?

D = ICHAR(ACARD(L2:L2)) - ICHAR("0") !Taste the digit candidate.

IF (D < 0 .OR. 9 < D) GO TO 20 !Suitable?

X = X*10 + D !Yes. Accept as before.

DD = DD + 1 !But now, count the decimal digits.

ADIGIT = .TRUE. !There may have been none before the decimal point.

GO TO 11 !Carry on.

Consider any exponent part, following an "E" or "D", etc..

20 IF (INDEX("EeDd",ACARD(L2:L2)

L2 = L2 + 1 !Step past it.

IF (L2.GT.LA) GO TO 30 !Sudden stop?

IF (ACARD(L2:L2).EQ."+") GO TO 21 !A (redundant) plus sign?

IF (ACARD(L2:L2).NE."-") GO TO 22 !A - sign to notice?

PNEG = .TRUE. !Yes. Noticed.

21 L2 = L2 + 1 !Advance one.

IF (L2.GT.LA) GO TO 30 !As ever, after every advance, fear the brink.

22 D = ICHAR(ACARD(L2:L2)) - ICHAR("0") !Check for a digit.

IF (D < 0 .OR. 9 < D) GO TO 30 !It is one?

P = P*10 + D !Yes. Build up the power part.

GO TO 21 !And look some more.

Combine the components into one number then correct the power of ten.

30 IF (XNEG) X = -X !Correct the sign of the number.

IF (PNEG) P = -P !Correct the sign of any exponent.

P = P - DD !Now adjust the power of ten for decimal digits.

IF (P .EQ. 0) GO TO 40 !No net fiddle! Yay!

D = ABS(P) !Oh well. Some power is required.

POW = TEN(MOD(D,8)) !Gnash the bothersome low-order bits in one go.

D = D/8 !Now for the higher-order bits beyond the scope of my table.

IF (D.LE.0) GO TO 32 !Are there any worthy of my regard?

TENS = TEN(8) !Yes! Prepare to acknowledge them.

31 IF (MOD(D,2) .EQ. 1) POW = POW*TENS !Bite this bit?

D = D/2 !So much for that level.

IF (D .EQ. 0) GO TO 32 !Are we there yet?

TENS = TENS*TENS !No. Crank up another level,

GO TO 31 !And keep trying.

32 IF (P .GT. 0) THEN !Because 0.1 = Binary .0001100110011001100110011

X = X*POW !It is not represented in base two.

ELSE !So *10 etc. is accurate,

X = X/POW !As is /10, etc.

END IF !But *0.1 is inaccurate.

Complete the action.

40 V = X !The result at last.

IF (TRACE%EATREAL) THEN !Are we under inspection?

WRITE (BURP(3:),*) X !Alright, reveal what was found.

BURP(1:2) = "v=" !Squeeze in a prefix.

CALL SHOWPLACE(BURP) !Let the world know.

END IF !So much for worries.

IF (ADIGIT) THEN !Something worked: advance the scan.

L1 = L2 !Here is where I stopped looking.

IF (L1.LE.LA) THEN !Off the end?

L2 = L1 + 1 !No. Co-ordinate fingers in case of a non-blank.

IF (ACARD(L1:L1).EQ." ") CALL PASSSPACE !Only if it is a blank.

END IF !Righto, the next non-blank is fingered.

END IF !And L2 is one beyond it if L1 is not off the end.

EATREAL = ADIGIT !Report how we feel.

CALL $SUBOUT("EatReal") !I am done.

RETURN !So farewell.

END FUNCTION EATREAL !Note that the number read is the parameter, NOT the result.

This prog. is part of a larger collection of routines for the speedy scanning of vast input files. A record of input is read into character variable ACARD, whose last non-blank position is fingered by LA. The scan proceeds from L1, initially set to finger the first non-blank character in ACARD. Each invocation of EATREAL further advances L1 (should a number be read), leaving L1 fingering the next non-blank after the number. This would usually be a comma, and the loop invoking EATREAL invokes a PASSBY(",") to see if it should try for another number.

If the numbers are inside your programme, then you can multiply them by 100, round to an integer and write them out.

eg V = 1623.88

...

WRITE (6,*) INT(V*100) !Function INT should round to the nearest integer.

Alternatively,the furrytran FORMAT statement allows the use of the rather odd P specifier which for F-format will shift the decimal place (changing the value presented), as in

WRITE (6,66) V

66 FORMAT(2PF9.0)

would give 162388. but that is still with a decimal point present, and there are no leading zeros.

You could wtite the output to a character variable, and then fiddle the text to taste (removing the decimal point and adding the leading zeroes), or, if your furrytran supports it, you could use an extension of the I-format. I6 produces a six-digit field, with leading spaces, but I6.6 generates leading zeroes to supply at least six (the .6) digits. Thus,

WRITE (6,66) INT(V*100)

66 FORMAT(I6.6)

Using integers means that you have to be sure that no number will go beyond the range of the integer.

Question has a verified solution.

Are you are experiencing a similar issue? Get a personalized answer when you ask a related question.

Have a better answer? Share it in a comment.

All Courses

From novice to tech pro — start learning today.

The .CSV file displays a 2 decilmal number 2.5 instead of 2.50. I need to convert that into 000250 or if the number is 1623.88 into 00162388.

</quote>

Are you saying that, given an input file with a line like:

2.5,1623.88

You want to write it out as:

00000250,00162388

(Note: I have 2 more zeroes with my 2.5 example than what you said above.)