0

This always results in 0 for me and I don't know why... Other examples on internet generally cause of division.

in Codeblocks same code results normally but in Atom I have this problem. please help.

#include <stdio.h>
#include <conio.h>

#define PI 3.14
int main() {
    float r,a,c;
    printf("enter radius: \n");
    scanf("%.2f",&r);
    c = r * PI * 2;
    a = r * r * PI;
    printf("area:%.2f circumference:%.2f \n",c,a );
    return 0;
}
woz
  • 544
  • 6
  • 22
  • 3
    Can you print r as well? Perhaps it is not getting set properly. – Max Jan 16 '19 at 22:46
  • 0 area or 0 circumference? Or 0 both? – DYZ Jan 16 '19 at 22:47
  • 5
    Why are you using `scanf("%.2f",&r);` instead of `scanf("%f",&r);`? – UnholySheep Jan 16 '19 at 22:47
  • 1
    Yes, with `scanf("%f",&r);` your code will work. – marko Jan 16 '19 at 22:51
  • 1
    Try rising the warning level and check the return value of `scanf`: https://wandbox.org/permlink/dorT1xljDQl7zlEy – Bob__ Jan 16 '19 at 22:55
  • The course value for pi reminds me of [π, such as 3.2](https://en.wikipedia.org/wiki/Indiana_Pi_Bill). – chux - Reinstate Monica Jan 16 '19 at 23:01
  • it was a typing mistake .. I'm emberassed , sorry for unnecessary question. –  Jan 16 '19 at 23:02
  • 1
    @user9019746 The real mistake is not the typo. but not using a good compiler with [enough warnings enabled](https://stackoverflow.com/questions/54226519/calculation-in-c-program-always-results-in-0#comment95279258_54226519). – chux - Reinstate Monica Jan 16 '19 at 23:04
  • The recipe for *Undefined Behavior* - failure to check the return of `scanf` is... – David C. Rankin Jan 16 '19 at 23:12
  • `%.2f` is simply an invalid `scanf()` conversion specification, starting at the `.` — see the POSIX specification for [`scanf()`](http://pubs.opengroup.org/onlinepubs/9699919799/functions/scanf.html), which is a superset of the one for the C standard. So, if anyone checked the return value from `scanf()` as you should, you'd find that it reported an error. And hence you get whatever you get in the value read — no assignment takes place because the conversion failed because the conversion specification was invalid. Always test that your I/O calls succeed (especially input). – Jonathan Leffler Jan 16 '19 at 23:15
  • Which C compiler can you advice me ? –  Jan 16 '19 at 23:32
  • @user9019746 [gcc](https://gcc.gnu.org/install/download.html) is quite good. – chux - Reinstate Monica Jan 16 '19 at 23:48

2 Answers2

4

C11 7.21.6.2p3 says the following of fscanf et al:

3 [...] Each conversion specification is introduced by the character %. After the %, the following appear in sequence:

  • An optional assignment-suppressing character *.
  • An optional decimal integer greater than zero that specifies the maximum field width (in characters).
  • An optional length modifier that specifies the size of the receiving object.
  • A conversion specifier character that specifies the type of conversion to be applied.

The length modifier means the extra letter(s) such as l in %lf meaning double. Notice that while %2f would be valid and would mean that only to 2 characters of input can be consumed, it is nowhere said that you can write %.2f, i.e. %.2f is an invalid conversion specification, and hence the behaviour is undefined (C11 7.2.6.2p13).

1

If there's no reason you want to use %.2f to scan, just using %f will work

#include <stdio.h>
#include <conio.h>

#define PI 3.14
int main() {
    float r,a,c;
    printf("enter radius: \n");
    scanf("%f",&r);
    c = r * PI * 2;
    a = r * r * PI;
    printf("area:%.2f circumference:%.2f \n",c,a );
    return 0;
}

Example:

daniel@daniel-FX503VM:~/Documents/test$ ./zero 
enter radius: 
1
area:6.28 circumference:3.14 

The .2 in the printf is a printing format specifier, and shouldn't have an impact on a scanf

Where you're putting the .2 in the scanf is actually the width field,which specifies the maximum number of characters to be read in the current reading operation (optionally). However, in this context, .2 characters as a width is not a meaningful sentiment, seeing as the width is required to be an integer.

If what you're actually trying to do is only read 2 characters, you could say

scanf("%2f", &r);

But be warned that the '.' would also count as a character.If you specifically just want the output to be two decimal places, then the proposed code above should suffice. If you want to round it internally, I'd suggest you read this post

Daniel
  • 854
  • 7
  • 18
  • @chux my apologies, I didn't explain myself well. I updated my answer to have a bit of a better explanation - but if you want to suggest an edit, I'd be glad to improve the answer =) – Daniel Jan 16 '19 at 23:04
  • The `"."` in `"%.2f"` makes the specifier invalid. The rest of the specifier is irrelevant. The `"2"` is not the width because of that pesky `"."`. – chux - Reinstate Monica Jan 16 '19 at 23:07
  • Would provide a much more thorough learning experience with `if (scanf("%f",&r) != 1) { fputs ("error: invalid input.\n", stderr); return 1; }` to handle *matching failures*....(or the user canceling input by generating a manual `EOF`) (nit: no need for `'\n'` at the end of the prompt -- that will be provided by pressing `[Enter]`) – David C. Rankin Jan 16 '19 at 23:08
  • @DavidC.Rankin Note: `'\n'` helps insure flushing of `stdout` when it is line buffered. Of course `fflush(stdout)` is best. – chux - Reinstate Monica Jan 16 '19 at 23:46
  • Very true, but the call to `scanf` also forces the flush while it blocks for input. – David C. Rankin Jan 16 '19 at 23:47
  • @DavidC.Rankin "scanf also forces the flush" --> news to me. Any ref to support that? Sounds implementation specific. – chux - Reinstate Monica Jan 16 '19 at 23:50
  • Hmm... Now you have me curious. I'll have to find the reference and it may very well be implementation defined. (but it is the reason `printf ("prompt: ");` works without `fflush` on 99% of the systems. – David C. Rankin Jan 16 '19 at 23:52
  • @chux, I was specifically recalling [GNU libc - 12.20.2 Flushing Buffers](https://www.gnu.org/software/libc/manual/html_node/Flushing-Buffers.html) which would make it implementation defined. – David C. Rankin Jan 17 '19 at 00:23
  • @chux Also applicable is [C11 Standard - 7.21.3 Files(p3)](http://port70.net/~nsz/c/c11/n1570.html#7.21.3p3) which has the same effect, *"characters are intended to be transmitted as a block to the host environment when a buffer is filled... or when input is requested on a line buffered stream that requires the transmission of characters from the host environment."* – David C. Rankin Jan 17 '19 at 00:32
  • @DavidC.Rankin ... Support for these characteristics is implementation-defined, – chux - Reinstate Monica Jan 17 '19 at 01:58
  • @chux so let me pick your brain a bit more to make sure I'm clear on what you are saying. The standard specifies how input functions affect *line buffered* streams, but it is up to the implementation to determine the default buffering for the standard streams, e.g. whether `stdout` is *line buffered*, *fully buffered* or *unbuffered*. – David C. Rankin Jan 17 '19 at 02:40