-1

So, I'm creating a program that calculates the area of a triangle, and I need it to tell the user if he typed a letter or a negative number, in order, I created the code: I need to use isdigit

#include <stdio.h>
#include <stdlib.h>
#include <math.h>
#include <ctype.h>

int main () {
    float a, b, c;
    float s=0, ar1=0, ar2=0;
    printf("Inform the value of side A.");
    fflush(stdin);
    scanf("%f",&a);
    while(a<=0||isdigit((int)a)){
        printf("Invalid value.");
        fflush(stdin);
        scanf("%f",&a);
    }printf("Inform the value of side B.");
    fflush(stdin);
    scanf("%f",&b);
    while(b<=0||isdigit((int)a)){
        printf("Invalid value.");
        fflush(stdin);
        scanf("%f",&b);
    }printf("Inform the value of side C.");
    fflush(stdin);
    scanf("%f",&c);
    while(c<=0||isdigit((int)a)){
        printf("Invalid value.");
        fflush(stdin);
        scanf("%f",&c);}
         s=((a+b+c)/2);
        ar1=(s*(s-a)*(s-b)*(s-c));
        ar2=pow(ar1,0.5);
   printf("The semiperimeter is %f",s);
   printf("The area of the triangle is%f",ar2);
   system ("pause");
   return 1;
}

But, when I compile/run it, and type "x", or "blabla" when I was supposed to type a number, nothing happens, and the program doesn't warn me, what should I do?

Sami Kuhmonen
  • 30,146
  • 9
  • 61
  • 74
  • Also, I'm a beginner, so I don't know many functions in C – Rafael Vignoli Jun 05 '15 at 06:11
  • Remove all those `fflush(stdin)` . It is UB on many implementations. – Spikatrix Jun 05 '15 at 06:15
  • What's UB? And I removed it, nothing happened – Rafael Vignoli Jun 05 '15 at 06:26
  • scanf is probably not the right tool for your requirements. See [this](https://stackoverflow.com/questions/18210406/check-if-input-is-float-else-stop) which solves the same problem and an explanation for why scanf will not do the right thing for you. – kaylum Jun 05 '15 at 06:35
  • @RafaelVignoli , UB means Undefined Behavior. Basically, it means that anything can happen. Google it and you'll see what it is. – Spikatrix Jun 05 '15 at 06:41

1 Answers1

1

First of all, using fflush on stdin is Undefined Behavior as per the C11 standard, although it is well defined on some implementations.

Secondly, you can't use simply use isdigit that way. Once %f sees invalid data such as characters, the scanf terminates and the corresponding argument is left untouched. Also, using isdigit on an uninitialized variable leads to Undefined Behavior.

What you can do is check the return value of scanf. All the three scanfs in your code returns 1 if successful.


Fixed Code:

#include <stdio.h>
#include <stdlib.h>
#include <math.h>
#include <ctype.h> //Unused header


void flushstdin() //Removes all characters from stdin
{
    int c;
    while((c = getchar()) != '\n' && c != EOF); //Scan and discard everything until a newline character or EOF
}

int main () {

    float a, b, c;
    float s=0, ar1=0, ar2=0;

    printf("Inform the value of side A\n");
    //fflush(stdin); Avoid this to make your code portable
    while(scanf("%f",&a) != 1 || a <= 0){
        printf("Invalid value\n");
        flushstdin(); //Alternative way to flush stdin
    }

    printf("Inform the value of side B\n");
    //fflush(stdin);
    while(scanf("%f",&b) != 1 || b <= 0){
        printf("Invalid value\n");
        flushstdin(); //Alternative way to flush stdin
    }

    printf("Inform the value of side C\n");
    //fflush(stdin);
    while(scanf("%f",&c) != 1 || c <= 0){
        printf("Invalid value\n");
        flushstdin(); //Alternative way to flush stdin
    }

    s=((a+b+c)/2);
    ar1=(s*(s-a)*(s-b)*(s-c));
    ar2=pow(ar1,0.5);

    printf("The semiperimeter is %f\n", s);
    printf("The area of the triangle is %f\n", ar2);
    system ("pause");
    return 0; // 0 is usually returned for successful termination
}

Also, it is better to add newline characters at the end of the strings in printf as seen in the above program. They

  • Improve readability
  • Flushes the stdout
Spikatrix
  • 20,225
  • 7
  • 37
  • 83