Standard form in C - c

After a few hours of searching I have not been able to find an answer, but if this is a duplicate please point me in the correct direction.
Will a C program accept a standard form input into something like scanf("%f",&float); from the keyboard. Standard form is writing a number like 2400 as 2.4E3 if this helps you understand what I am asking.
I must stress this MUST be from the keyboard.

Yes.
scanf works identically, regardless of whether stdin is connected to a terminal, a file, or some other input stream.
The %a, %e, %f, %g scanf format codes all do the same thing: interpret the longest string which would be acceptable to strtod (§7.21.6.2/12). (And so do %A, %E, %F and %G -- paragraph 14 of the same clause.) The redundancy is because scanf formats accepts the same format codes as printf.
strtod accepts any of the following (§7.22.1.3/3):
a nonempty sequence of decimal digits optionally containing a decimal-point character, then an optional exponent part as defined in 6.4.4.2;
a 0x or 0X, then a nonempty sequence of hexadecimal digits optionally containing a decimal-point character, then an optional binary exponent part as defined in 6.4.4.2;
INF or INFINITY, ignoring case
NAN or NAN(n-char-sequenceopt), ignoring case in the NAN part,…

Yes, it is being accepted from my terminal and also the IDEone interpreter (added it in stdin which is the same as "from the keyboard").
And probably a typo, but you have missed the "" in
scanf("%f", &float)

Related

sscanf("0X80.9", "%f", &value) sets value to a hex float not a float

I have some code that reads letter value pairs. It can be simplified as:
float value = 0.0;
sscanf("0X80.9", "%f", &value);
In Visual Studio 2013, value = 0
In Visual Studio 2015 and above, value = 128.5625 (i.e. 0x80 in hex = 128 in decimal)
Anyone know why this has changed? More importantly, anyone know how to make it work like it used to?
C99 added a new feature, hexadecimal floating-point constants. It also added new formats to the *scanf() functions. (A hexadecimal floating-point constant in source code must have an exponent part; for scanf, the exponent is optional.)
scanf reads as much of the input as it can that's consistent with the format. For pre-1999 C, this is the initial "0"; the following "X80.9"is left. For C99, "0X80.9" is valid, and is converted to the floating-point value 128.5625. (The format is the same as what's accepted by strtof().)
The C++ standard includes most of the C standard library by reference. It didn't update to the C99 version of the C library until c++2012.
Most likely Visual Studio 2015 supports C++12 or later, and Visual Studio 2013 doesn't.
Since the new behavior is now standard, I suggest adapting your code to deal with it rather than trying to force the old behavior. If there's a way to make VS2015 behave in the old way, it should be documented.
C99 adds hexadecimal floating point constants. The printf() formats are %a and %A; there are the corresponding scanf() formats too. But as with %f, %e, %g, the scanf() floating point formats all accept any floating point format (so %f can read output printed using %e, etc).
ISO/IEC 9899:2011 — §6.4.4.2 Floating constants
floating-constant:
decimal-floating-constant
hexadecimal-floating-constant
…
hexadecimal-floating-constant:
hexadecimal-prefix hexadecimal-fractional-constant
binary-exponent-part floating-suffixopt
hexadecimal-prefix hexadecimal-digit-sequence
binary-exponent-part floating-suffixopt
…
hexadecimal-fractional-constant:
hexadecimal-digit-sequenceopt .
hexadecimal-digit-sequence
hexadecimal-digit-sequence .
binary-exponent-part:
p signopt digit-sequence
P signopt digit-sequence
hexadecimal-digit-sequence:
hexadecimal-digit
hexadecimal-digit-sequence hexadecimal-digit
floating-suffix: one of
f l F L
(The hexadecimal prefix is 0x or 0X of course.)
The 0X80.9 notation doesn't exactly correspond to the notation required of hexadecimal floating point constants in C source code because there is no 'binary-exponent-part', but …
the scanf() family of functions can only push back 1 character, so they can't tell there's a problem until far too late, so it ends up treating it as if there was a P0 at the end. The scanf() functions read data items according to a conversion specification:
An input item is read from the stream, unless the specification includes an n specifier. An
input item is defined as the longest sequence of input characters which does not exceed
any specified field width and which is, or is a prefix of, a matching input sequence.285)
The first character, if any, after the input item remains unread.
the strtod() family of functions accept:
— a 0x or 0X, then a nonempty sequence of hexadecimal digits optionally containing a
decimal-point character, then an optional binary exponent part as defined in 6.4.4.2;
and the scanf() family of functions accept:
a, e, f, g
Matches an optionally signed floating-point number, infinity, or NaN, whose
format is the same as expected for the subject sequence of the strtod
function. The corresponding argument shall be a pointer to floating.
In the 1999 C Standard it was added that the input for strtod (which is what %f in scanf refers to) can include a 0x or 0X prefix to indicate a hex float.
16 years later it seems Microsoft have finally gotten around to doing the work.
Your best option would be to move forward with the new behaviour, rather than trying to invoke compiler flags to get the old behaviour (which may not even be possible, I don't know).
To emulate the old behaviour in your project you could use code like:
double my_scan(char const *s)
{
double value = 0.0;
if ( ! memcmp(s, "0X", 2) )
sscanf(s, "%f", &value);
return value;
}
or whatever would suit your use case. Perhaps you might end up writing your own tokenizer.

Read scientific notation scanf

I am developing a program which should have only one scanf function and it should be able to accept input in scientific notation and real numbers.
Any help will be appreciated
According to the scanf documentation:
%f matches a floating-point number. The format of the number is the same as expected by strtof().
Looking at the strtof documentation
(optional) e or E followed with optional minus or plus sign and nonempty sequence of decimal digits (defines exponent)
Thus, you can use the %f specifier to read numbers in e notation. That is,
1e-3 is 1 * 10 ^ -3.

format specifier for double in scanf

I wrote this program for getting a double input:
double n;
scanf("%lf",&n);
while(fgetc(stdin)!='\n')
return 0;
printf("%lf",n);
This program is supposed to take double as input. Provided that %lf is the format specifier for double in scanf, I used it. But for inputs of a digit followed by e. ex.(3e), the input is being read without errors. But during processing of the same variable, it is discarding the e and only considering 3 as is shown by the printf statement. What is the cause of such behaviour?
Following the rationale given in defect report #22 (http://www.open-std.org/jtc1/sc22/wg14/docs/rr/dr_022.html), functions like scanf (with %lf) and strtod should consume as much input as satisfies the expected format for the floating point constant. This means that they should consume the e character in "3e" even though the e character is not followed by the actual exponent value (the exponent value is required to be present by 6.4.4.2).
This applies in equal degree to %lf and %f. In my experiments they behave exactly the same on this input. (Of course, %f requires target variable of type float.)
However, even after consuming both 3 and e from the input stream, I would expect scanf (and strtod) to recognize "3e" as an invalid representation of a floating point number (since, again, 6.4.4.2 requires the exponent value to be present) and act accordingly. In my experiment scanf successfully read 3.0. This I cannot explain yet.

LynxOS strtod not the same as Linux

It seems that LynxOS's implementation of strtod doesn't handle all the same cases as that of Linux, or for that matter Solaris. The problem I have is that I am trying to parse some text that can have decimal or hexadecimal numbers in it.
On Linux I call
a = strtod(pStr, (char **)NULL);
and I get the expected values in a for input strings such as 1.234567 and 0x40.
On LynxOS, the decimal numbers parse correctly, but the hex parses simply as 0 due to stopping when it hits the 'x'. Looking at the man pages, it seems that LynxOS's strtod only supports decimal strings in the input.
Does anyone here know of an alternative that will work on both Lynx and Linux?
Quote from the Standard (7.20.1.3) ( http://www.open-std.org/JTC1/sc22/wg14/www/docs/n1256.pdf )
The expected form of the subject sequence is an optional plus or minus sign, then one of
the following:
— a nonempty sequence of decimal digits optionally containing a decimal-point
character, then an optional exponent part as defined in 6.4.4.2;
— a 0x or 0X, then a nonempty sequence of hexadecimal digits optionally containing a
decimal-point character, then an optional binary exponent part as defined in 6.4.4.2;
— [...]
So, the compiler you're using on LynxOS is not a C99 compiler.
My copy of the C89 Standard has no reference to the 0x prefix:
4.10.1.4 The strtod function
[...]
The expected form of the subject sequence is an optional plus or
minus sign, then a nonempty sequence of digits optionally containing a
decimal-point character, then an optional exponent part [...]
strtod takes 3 arguments, not two. If you had prototyped it by including the correct header (stdlib.h), your compiler would have issued an error. Since you're calling a function with the wrong signature, your program has undefined behavior. Fix this and everything will be fine.

What Is "\t%.10g\n"

I'm new at Bison, but in C/C++ no and at this time of development and regular expressions i never heard something like this, only the \n that's used for a new line, but i want to know what is the explanation of \t%.10g, that in the code is like this:
line: '\n'
| exp '\n' { printf ("\t%.10g\n", $1); }
;
Best Regards.
It means "print a tab character (\t) followed by a floating point number with 10 decimal places, either in scientific or fixed point notation depending on the order of magnitude (%.10g), followed by a newline (\n)".
Have a look at the printf reference to decode the pattern:
g Use the shorter of %e or %f
e Scientific notation (mantise/exponent) using e character
f Decimal floating point
Thus, %.10g prints a decimal number with ten significant digits.
It's not a regex but a printf format specification : Print a tab character followed by a floating point number with 10 digits behind the decimal point, either %f (floating point notation) way or %e (scientific notatation) way, whichever is shorter, and end with a newline.
man printf

Resources