0

How do I print invalid when someone enter big or small letters, because supposedly they only enter floats between 0 to 10.

I tried coding like this

It went so wrong.

#include<stdio.h>


int main()
{
    int trial=0;
    float judge1=0,judge2,judge3,judge4,judge5;
    char a;

    printf("\n%90s","Welcome to the constentant score calculator program :)");

    printf("\n\n\n\n\n\rKindly enter the constentant score by 5 respected 
 judges:");

    do
    {
        printf("\n\nScore by JUDGE 1 (0-10):\t");
        scanf("%f",&judge1);

         if ((judge1>-1)&& (judge1<11) )
             printf("The constentant got %.2f from the judge",judge1);
         else
            printf("\aPlease input a valid score between 0 and 10:");
     } while ((judge1<0) || (judge1>10)||(judge1=a>96) && (judge1=a<123)|| 
 (judge1=a<91) && (judge1=a>64));
}

okay this is my second code

#include<stdio.h>

int main()
{
    float judge1;

    printf("\n%90s","Welcome to the constentant score calculator program :)");

    printf("\n\n\n\n\n\rKindly enter the constentant score by 5 respected 
judges:");

    printf("\n\nScore by JUDGE 1 (0-10):\t");
    scanf("%f",&judge1);

    if ((judge1>-1) && (judge1<11))
      printf("The constentant got %.2f from the judge",judge1);
    else
        printf("\aPlease input a valid score between 0 and 10:");
    }
}
dbush
  • 205,898
  • 23
  • 218
  • 273
  • what is `char1` value ? – ntshetty Dec 27 '18 at 14:37
  • char1 does not have value....i use it to print invalid when inserting letters @ThiruShetty – Aathf Addli Dec 27 '18 at 14:47
  • @P__J__: `judge1==char1>96` is not always zero, nor is `judge1==char1<123` always 1. If `judge1` is 1 and `char1` is `'|'`, then `judge1==char1>96` is 1 and `judge1==char1<123` is 0. – Eric Postpischil Dec 27 '18 at 14:47
  • @P__J__ yes,i want it to work that way,so if they insert letters,it will print "Please input a valid score between 0 and 10:");",but unfortunately it doesnt work that way. – Aathf Addli Dec 27 '18 at 14:52
  • @ThiruShetty char1 value is depends on the letters,by using ASCII code. – Aathf Addli Dec 27 '18 at 14:54
  • @AathfAddli You were given an hint: `char1` is never assigned a value, so it doesn't make sense to compare it to anything unless you do assign to it. – dbush Dec 27 '18 at 14:56
  • then comparison is wrong as suggested others – ntshetty Dec 27 '18 at 14:57
  • what you do with char1 has no sense at all. Why you do not check scanf returns 1 ? – bruno Dec 27 '18 at 14:58
  • judge1==char1>96 will be true only if judge == 0 && char1 < 96 or judge1 == 1 and char 1 > 96. For all other values of judge1 and char it will be zrero – 0___________ Dec 27 '18 at 15:02
  • @dbush I assigned it to the judge1 value,as for example;if the value entered equals to k,the judge1=k,so if judge1=char1<93,it means k is assigned to the ASCII code – Aathf Addli Dec 27 '18 at 15:05
  • @AathfAddli You did **not** assign anything to `char1` (now `a` in the modified code). It isn't magically set when you set `judge1`. – dbush Dec 27 '18 at 15:23

3 Answers3

2

When you use the "%f" as the format string for scanf, it will read only characters that are valid for a floating point type and will stop reading if it detects any other characters. So if someone types "abc", nothing is written to judge1 and those characters are left in the input buffer to be read again. You'll then get stuck in an infinite loop reading those same characters.

Also, this expression doesn't make sense:

judge1=a>96

> has higher precedence than ==, so it is equivalent to:

judge1=(a>96)

Assuming a is assigned a value, a>96 compares that value with 96 and evaluates to either 0 or 1. Then you assign this value to judge1, overwriting what was read from the user. Assuming you meant to use == this doesn't make sense either. That being the case, either judge1==0 or judge1==1 is evaluated depending on the result of a>96. So the above expression will only be true if judge1 is 1 and a is greater than 96 or judge1 is 0 and a is less than or equal to 96.

Another problem is that a is never assigned a value. You seem to be under the impression that when you call scanf("%f",&judge1); that the first character read is written to a. There is no link that causes that to happen, so a is left uninitialized.

What you want to do instead is read in a line of text using fgets, then using strtof to read a float. The strtof function accepts the address of a pointer as the second parameter to let you know where in the string the parsing stopped. So if this pointer does not point to the null terminator at the end of the string (or to a newline character, since fgets reads and stores the newline), then you know you read a non-float character.

float judge1;
char line[100];
char *p;
int invalid_input;

do {
    invalid_input = 0;
    fgets(line, sizeof(line), stdin);
    errno = 0;
    judge1 = strtof(line, &p);
    if (errno || ((*p != 0) && (*p != '\n')) || (judge1 < 0) || (judge1 > 10)) {
        printf("Please input a valid score between 0 and 10:");
        invalid_input = 1;
    } else {
        printf("The constentant got %.2f from the judge\n ",judge1);
    }
} while (invalid_input);
dbush
  • 205,898
  • 23
  • 218
  • 273
  • being a beginner in C,so im sorry,that i cant really understand every meaning of yours :(,So,can you help me to edit my code,so that when user enter a letter it will print "Please enter a valid input" instead of "The constentant score is 0.00" or to infinite loop ....i really dont get it sorry. – Aathf Addli Dec 27 '18 at 15:27
  • @AathfAddli The code in my answer does what you need it to do. Read everything again carefully. – dbush Dec 27 '18 at 15:30
  • would you mind to look on my second code?i edited my post,so the question for the second code it that,why is it when i enter letter "k" as input,it displays "The constentants got 0.00 score from the judge"?Isnt it supppose to display "Please enter a vlid input between 0 and 10"? – Aathf Addli Dec 27 '18 at 15:38
  • @AathfAddli It has the same problem as the first piece of code, as described in the first paragraph of this answer, and is addressed in the code in the answer. – dbush Dec 27 '18 at 15:40
  • so lets say,referring to your first paragraph,if i use %f,and the input entered is abc,i will always go to the infinite loop because it wont read it right? – Aathf Addli Dec 27 '18 at 16:24
  • @AathfAddli Correct. `scanf` would see the 'a' and stop, returning 0. This tells you that nothing was stored. On the next attempt, it would again see the 'a' and stop. You would then need to call `getchar` to flush those characters out of the buffer until you read a newline. – dbush Dec 27 '18 at 16:27
1

First, check the return value of scanf. If it fails to match the item it will return 0. Then you can check whether the number entered is within bounds:

int r, judge1;
...
r = scanf("%d", &judge1);
if(r != 1)
{
    printf("invalid input\n");
    while((r = fgetc(stdin)) != EOF && r != '\n');
}
else if((judge1 < 0) || (judge1 > 10))
    printf("input out of range\n");
else
    printf("valid input\n");
mnistic
  • 10,866
  • 2
  • 19
  • 33
  • he need to check even ASCII characters – ntshetty Dec 27 '18 at 14:56
  • yes this code will work fine,but this is not the answer that im looking for,my problem is when entering the letter,for example k,it will print "The constentant score is 0.00",by looking through my codes,it should display"Please enter a valid input between 0 and 10",there you go,i edited my code....please help – Aathf Addli Dec 27 '18 at 15:08
  • @AathfAddli you are wrong, if you follow what mnistic did it will do what you expect. – bruno Dec 27 '18 at 15:42
  • @mnistic you must compare the result of _scanf_ to 1 to manage all the error cases – bruno Dec 27 '18 at 15:45
  • @bruno i see,but what does this mean if(!r) – Aathf Addli Dec 27 '18 at 15:46
  • you missed the EOF case – bruno Dec 27 '18 at 15:48
  • to always compare with the expected read element number is the best way, here it is 1 – bruno Dec 27 '18 at 15:51
  • but why r assign to 1??what does it relate when someone enters a letter? – Aathf Addli Dec 27 '18 at 15:57
  • @AathfAddli if the entered value is an integer (compatible with _%d_) scanf return 1, in _all_ the other cases the value will not be 1. It is 1 because 1 element has to be read. I encourage you to read the documentation about _scanf_ – bruno Dec 27 '18 at 16:14
  • @AathfAddli It's not assigning 1 to `r`, it's comparing `r` to 1. Note that you may want to [clear the input buffer on invalid input](https://stackoverflow.com/a/35899225/4454124) or go with the dbush's answer here. – mnistic Dec 27 '18 at 16:27
0

The problem is you have the bad charachter stuck in the stream. The solution is here: scanf fails why?. The suggested thing to do from John Bode is to use a getchar to get it out. Also apply the check mnistic suggested and it should work.

it doesn't offer anything and it only messes with the greater picture.