[comp.sys.ibm.pc] Turboc floating scanf

vail@tegra.UUCP (Johnathan Vail) (01/11/89)

I am using the "latest" version of TurboC and am trying to use scanf
to read floats.  I give tcc a '-f' or '-f87' switch but I still get a
run-time error from scanf when it tries to read in a float.

Is there something missing?  I couldn't find anything in the books to
enlighten me.  The only scanf I could find were in the cX.lib s.

Thanks...

"History is made at night.  Character is what you are in the dark!" 
  - Dr. Lizardo, "Buckaroo Banzai"
 _____
|     | Johnathan Vail  | tegra!N1DXG@ulowell.edu
|Tegra| (508) 663-7435  | N1DXG @ 145.110-, 444.2+, 448.625-
 -----

jacobs%cmos.utah.edu@wasatch.UUCP (Steven R. Jacobs) (01/11/89)

In article <370@atlas.tegra.UUCP> vail@tegra.UUCP (Johnathan Vail) writes:
>I am using the "latest" version of TurboC and am trying to use scanf
>to read floats.  I give tcc a '-f' or '-f87' switch but I still get a
>run-time error from scanf when it tries to read in a float.

I've seen a problem in Turbo C that sounds like the one you describe,
but it is more subtle than merely failing to handle floats in scanf().
For example, the program shown below compiles and executes correctly.
(compiled with "tcc foo1.c", the '-f' or '-f87' are not needed)

----------- foo1.c ------------
#include <stdio.h>
   
main()
{
float y;

   printf("Input for foo1: ");
   scanf("%f", &y);
   printf("... %f\n", y);
}
---------- end of foo1.c -------

The bug I have seen fails to handle floats in scanf(), but only
when all references to floats are through pointers to structures
which contain floats.  For example, the following program will compile,
but fails to run to completion.

----------- foo2.c ------------
#include <stdio.h>
   
typedef struct { float y; } FL_STRUCT;
FL_STRUCT fls;
main()
{
FL_STRUCT *ptr;

   ptr = &fls;
   printf("Input for foo2: ");
   fscanf(stdin, "%f", &(ptr->y));
   printf("... %f\n", ptr->y);
}
---------- end of foo2.c -------

When this program is run, the following two lines are produced as output:

	Input for foo2:  scanf : floating point formats not linked
	Abnormal program termination

The messages show that the program fails inside of scanf(), because
the linker wasn't smart enough to include support for floating point.
This same bug has appeared in all versions of Turbo C, and is the
only Turbo C bug that has given me problems.  The "fix" is to add
a dummy variable of type float and use that variable in at least one
scanf() call so that the floating point formats will be linked in.

In versions 1.5 and 1.0 of Turbo C, the mere existence of a float
that was assigned a value was enough to trigger the linking of
floating point formats, but in 2.0 there must be a scanf() call
which reads into a float that is not referenced through a structure
pointer.

A patched version of foo2.c is shown below, with changes which get
around the bug.  This is ugly, but it works.  The patch only needs to
be applied to one scanf() call in the program.

----------- foo2x.c ------------
#include <stdio.h>
   
typedef struct { float y; } FL_STRUCT;
FL_STRUCT fls;
main()
{
FL_STRUCT *ptr;
float tc_kludge;

   ptr = &fls;
   printf("Input for foo2: ");
   fscanf(stdin, "%f", &tc_kludge);
   ptr->y = tc_kludge;
   printf("... %f\n", ptr->y);
}
---------- end of foo2x.c -------

I hope that helps.
-----

Steve Jacobs  ({ihnp4,decvax}!utah-cs!jacobs, jacobs@cs.utah.edu)

dmurdoch@watdcsu.waterloo.edu (D.J. Murdoch - Statistics) (01/11/89)

In article <370@atlas.tegra.UUCP> vail@tegra.UUCP (Johnathan Vail) writes:
>
>I am using the "latest" version of TurboC and am trying to use scanf
>to read floats.  I give tcc a '-f' or '-f87' switch but I still get a
>run-time error from scanf when it tries to read in a float.

According to someone on CIS, this is a known bug.  A workaround is to 
include a reference to a procedure called "turboFloat()".  Don't call it;
stick it somewhere where the linker will see it but it won't get executed.
You can also fiddle around with the way you specify the value to be written.
Apparently the compiler only forgets the turboFloat reference in certain
complicated constructions.

Duncan Murdoch

dmurdoch@watdcsu.waterloo.edu (D.J. Murdoch - Statistics) (01/11/89)

In article <5407@watdcsu.waterloo.edu> I wrote:
>According to someone on CIS, this is a known bug.  A workaround is to 
>include a reference to a procedure called "turboFloat()".  Don't call it;

Sorry!  The procedure you should reference is "_turboFloat()".  Don't forget
the leading underscore.

Duncan Murdoch

wew@naucse.UUCP (Bill Wilson) (01/12/89)

From article <370@atlas.tegra.UUCP>, by vail@tegra.UUCP (Johnathan Vail):
> 
> I am using the "latest" version of TurboC and am trying to use scanf
> to read floats.  I give tcc a '-f' or '-f87' switch but I still get a
> run-time error from scanf when it tries to read in a float.
>
scanf is one of the worst C functions.  I would suggest that you create
a character buffer, read into it and use the atof function to convert
it to a float var.  For example:

       float x;
       char buf[12];

       buf[0]=10;
       gets(buf);
       x=atof(buf);
 
Please make sure to include the correct header files for these
routines (refer to your manual).

-- 
Bill Wilson                          (Bitnet: ucc2wew@nauvm)
Northern AZ Univ
Flagstaff, AZ 86011
{These views are mine and do not necessarily reflect those of my employer}

kneller@cgl.ucsf.edu (Don Kneller) (01/13/89)

In article <1114@naucse.UUCP> wew@naucse.UUCP (Bill Wilson) writes:
>From article <370@atlas.tegra.UUCP>, by vail@tegra.UUCP (Johnathan Vail):
>> 
>> I am using the "latest" version of TurboC and am trying to use scanf
>> to read floats.
>>
>scanf is one of the worst C functions.  I would suggest that you create
>a character buffer, read into it and use the atof function:
>       float x;
>       char buf[12];
>
>       gets(buf);
>       x=atof(buf);

gets() is also a terrible function to use.  It is too easy to overwrite
memory because gets() does not know how long the input buffer is.  It
is much safer to use fgets().

- don
-----
	Don Kneller
UUCP:		...ucbvax!ucsfcgl!kneller
INTERNET:	kneller@cgl.ucsf.edu
BITNET:		kneller@ucsfcgl.BITNET