0

The following is the code that I wrote. I feel like I have missed something with the pointer or might have made mistake in the calculation. But as for as I see, everything seems good for me but when I enter, for example: hello or anything else, it gives me 0.00 as output.

The below is correct

Enter a number: 
6
Your number is: 6.00

But this why?

Enter a number: 
h
Your number is: 0.00

Following is the complete code:

#include <stdio.h>
#include <stdlib.h>
#define SIZE 250
    
float myAtof(char *string, char *error);

int main() {
   char string[SIZE];            // Array declaration.
   float fnum1;
   char errorState=0;
    
   printf("Enter a number:\n");
   gets(string);
     
   fnum1=myAtof(string,&errorState);
    
   if (errorState == 0) {
      printf("Your number is: %.2f \n", fnum1);
   } else if (errorState == 1) {
      printf("Error has been occurred due to inappropriate input!\n");
   }
     
   return 0;
}
    

float myAtof(char* string, char* error) {        
   *error != '1';
    
   float num=  0;
   float decimalFlag = 1;
   int decimalNumberFound = 0;
    
   for (int i = 0; string[i]!= '\0'; i++) {
      char ch = string[i];
      if (ch != '.' && (ch < '0' || ch >'9')) {
         error ='1';
         return 0;
      }

      if (decimalNumberFound == 1 && ch == '.') {
         error = '1';
         return 0;
      } else {
         num =  num* 10 +  (ch - '0');
   
         if (decimalNumberFound == 1)
            decimalFlag *=  10;
      }
   }
    
   num = num / decimalFlag;
    
   return num; 
}
Eric Postpischil
  • 195,579
  • 13
  • 168
  • 312
  • 5
    The line `*error != '1';` doesn't do anything... And the line `error ='1';` doesn't do anything either. You need to turn on your compiler warnings. – Jerry Jeremiah Apr 20 '21 at 00:58
  • 1
    You also try to set `error` to a character `1`, but in `main()` you compare it to an integer. – Barmar Apr 20 '21 at 01:09
  • 1
    Write a few lines of code at a time and use a debuger to confirm that code works as intended. Once you are able to parse a single digit positive number, adapt your code for multiple digits. When that code works, add decimal point handling. When every valid number works add error handling. Even better would be to commit your code into git or another versionning software so that if something breaks at a later stage, you can compare working code with broken one. Even better, write unit test code for simplest to more complex cases and fix code to pass one extra test each time. – Phil1970 Apr 20 '21 at 01:39
  • also use one style of code. not put parentasies at the end of line at one point and baggineing of next in next, be consistant –  Apr 20 '21 at 01:41
  • 2
    Never use `gets`: https://stackoverflow.com/questions/1694036/why-is-the-gets-function-so-dangerous-that-it-should-not-be-used – William Pursell Apr 20 '21 at 01:48
  • Your post does not make your question clear. To clearly explain what you think is wrong with your program, state both the output or behavior you observe and the output or behavior you desire instead. For example, you have indicated you get the output “0.00”, but you did not state the output you expect instead is the error message “Error has been occurred due to inappropriate input!” The lack of that information led at least one person to misunderstand your question. – Eric Postpischil Apr 20 '21 at 11:16
  • If you don't like `0.00` what you prefer when converting letters `1.00` or maybe `-999.99`? – i486 Apr 20 '21 at 11:32

1 Answers1

0

Since your myAtof routine has a parameter for reporting an error and your main routine tests the error-reporting variable, errorState, presumably you expect the program to print an error message when you enter “h” or other non-numerals, and your question is why it prints “0.00” rather than the error message.

In the function declared with float myAtof(char* string, char* error), error is a pointer, and *error is the thing it points to. So, when the code executes error = '1';, that attempts to set the pointer to '1'. It does not change the thing it points to.

When you compiled this, the compiler issued a warning message, something like “warning: incompatible integer to pointer conversion assigning to 'char *' from 'int'”. You should not have ignored that message.

The function also contains the statement *error != '1';. That statement does nothing. It says to compare the value of *error to '1' to see if they are unequal. The result of the != operator is 1 or 0 indicating whether the values are unequal or not. But the statement does nothing with that result. It is just discarded, so the statement has no effect.

Nothing in your function changes the value of *error, so the thing it points to, errorState in main, is never changed. So main does not see that an error has occurred. It evaluates errorState==0 as true and executes printf("Your number is: %.2f \n", fnum1);.

To fix this, delete the statement *error != '1'; and change the two error = '1'; statements to *error = '1';.

Additionally, change '1' to 1. Setting *error to '1' sets it to the code for the character “1”. It does not set it to the value 1, which is what errorState == 1 tests for. Typically, an error status would be either 0 or 1, not 0 or '1'.

Also change else if (errorState == 1) to else. When you have an if and else that are intended to completely select between some condition X and its alternative, you do not need a second test. With your code if (X) { … } else if (Y) { … }, the first { … } is executed if X is true, the second { … } is executed if X is false and Y is true, and neither is executed if X is false and Y is false. But it should never be the case that X is false and Y is false—you want the program always to either have a number or have an error status. There should be only two possibilities, not three. So use just else, not else if.

(Conceptually, it is a bug for the program to have errorState be something other than 0 or 1, so the program would never have both X false and Y false if it were working, and the else if would be okay. But you did have a bug, and that would cause neither { … } to be executed. Designing the code to use else instead of an unnecessary else if makes it a little more resistant to misbehaving when there is a bug. Designing programs to be robust in this way is useful.)

Also pay attention to warning messages from your compiler. Preferably, tell the compiler to treat all warnings as errors, so that your program will not compile while warning messages remain. If you are using GCC or Clang, use the -Werror switch. If you are using Microsoft Visual C++, use /WX.

Eric Postpischil
  • 195,579
  • 13
  • 168
  • 312