Intel® Fortran Compiler
Build applications that can scale for the future with optimized code designed for Intel® Xeon® and compatible processors.
28459 Discussions

Reading a real number from a dialog box

sumitm
Beginner
568 Views

I have an issue where a number that I try to read in from a dialog bix gets converted to a 1000th of its value (inside a calculation when I print it out and it is never reassigned)if the user enters it without a dot like 2 instead of 2.0
The code to read it is simply

retlog =DlgGet (dlg, IDC_PropertyFactor,text)

read (text,'(F8.3)',IOSTAT=IERR) PropFactor
where PropFactor is defined as Real and text is character(10)

Is there any reason 2 will not be read in as a real number and need to write additional code to see if a dot exists in text

Thanks
0 Kudos
7 Replies
Steven_L_Intel1
Employee
568 Views
Use F10.0 instead of F8.3. The .3 causes an implicit decimal point to be inserted if there is none in the text.
0 Kudos
Paul_Curtis
Valued Contributor I
568 Views
A robust text-to-real parsing scheme will have the flexibility to deal with arbitrary and unanticipated non-conforming user input, and do its best to recover a meaningful value, or return an error message which will not crash your program. Using a simple format statement for this purpose does not meet any real-world UI test. Here is some sample code which illustrates this concept:

[bash]SUBROUTINE EditBoxGetReal (hwnd, controlID, argval, nulldefault) IMPLICIT NONE INTEGER(HANDLE), INTENT(IN) :: hwnd INTEGER, INTENT(IN) :: controlID REAL,INTENT(IN),OPTIONAL :: nulldefault REAL,INTENT(INOUT) :: argval INTEGER, PARAMETER :: maxchars = 40 CHARACTER(LEN=maxchars) :: contents REAL :: valu INTEGER :: status INTEGER :: pos, hour, minute CALL EditBoxReadText (hwnd, controlId, contents, maxchars) ! stop now if no data to convert pos = INDEX(contents, CHAR(0)) IF (is_empty(contents, pos)) THEN IF (PRESENT(nulldefault)) argval = nulldefault RETURN END IF CALL CStringToFortran (contents) contents = ADJUSTL(contents) ! allow ":" as a timefield delimiter pos = INDEX(contents, ':') status = 1 IF (pos > 0) THEN contents(pos:pos) = ' ' IF (pos == 1) THEN hour = 0 READ (contents, *, IOSTAT = status, END=5) minute ELSE READ (contents, *, IOSTAT = status, END=5) hour, minute END IF IF (status == 0) THEN SELECT CASE (minute) CASE (0:59) argval = FLOAT(hour) + FLOAT(minute)/60. END SELECT END IF RETURN ! regular real value ELSE IF (INDEX(contents, '.') == 0) THEN pos = INDEX(contents, ' ') contents(pos:pos) = '.' END IF READ (contents, '(F)', IOSTAT=status, END=5) valu IF (status == 0) argval = valu END IF 5 RETURN END SUBROUTINE EditBoxGetReal [/bash]
0 Kudos
sumitm
Beginner
568 Views
Thanks both for your help. I thought that the iostat=ierr would catch any errors if someone enters characters in place of numbers. Ideally it should warn if instead of real an integer is found but I appreciate the robust code also to cover any contingencies.
0 Kudos
WSinc
New Contributor I
568 Views
can you use G convesrion for input?
0 Kudos
Steven_L_Intel1
Employee
568 Views
F, E, D or G - all the same on input.
0 Kudos
joerg_kuthe
Novice
568 Views
Why not using simple list directed I/O?

READ(text,*,IOSTAT=iErr) PropFactor

Joerg Kuthe
www.qtsoftware.com

0 Kudos
Steven_L_Intel1
Employee
568 Views
Because list-directed I/O is generally more liberal about what is "allowed" than what programmers want. If the number has to be an integer, then use I10. If it can be an integer or a real, use F10.0.
0 Kudos
Reply