0

I made a Newton-Raphson Method program. But I have a question. As you see, "epsilon" and "x0" are float type and when I try to write something like "a" or "b", the program goes crazy. I want to prevent it. I want to tell "Please enter a number" to the user when something happens like this.

Can you help me about that? Thank you.

Code is below:

#include<conio.h>
#include<stdio.h>
#include<stdlib.h>
#include<locale.h>
#include<iostream>
#include<math.h>
#include<sstream>
#include <iomanip>
#include<time.h>
#define f(x) pow(x,5)-pow(x,4)-pow(x,3)+2*pow(x,2)
#define g(x) 5*pow(x,4)-4*pow(x,3)-3*pow(x,2)+4*x
using namespace std;

int main()
{
    setlocale(LC_ALL,"turkish");

    cout << "Problem 4" << endl << "---------" << endl << "Verilen y=(x^2)/(x+1) ve y=(x^3)/(x^3+2) fonksiyonlarının varsa kesim noktalarını bulan C programı\n" << endl;

    float x0, x1, f0, f1, g0, epsilon;
    int tahmin = 1, sinir=1000;

    cout << setprecision(6)<< fixed;

    bastan:
    
    cout << "Epsilon değerini giriniz: "; //Pay attention here. My question is about here.
    epsilonHata:
    cin >> epsilon;
    cout << endl;
    hata:
    cout << "İlk tahmin değerini giriniz: "; //Just like above, my question is about here too.
    cin >> x0;
    cout << endl;

    bla bla...
}
AEnic31
  • 47
  • 8
  • 2
    You mean if a user does not input some number but random characters? Declare a temporary `string` like `epsilon_str` for `cin`, then convert it to float using [atof](https://www.cplusplus.com/reference/cstdlib/atof/). You should read [how to ask a good question](https://stackoverflow.com/help/how-to-ask), espeecially *minimal reproducable example* part :) – Burak Apr 07 '21 at 18:41
  • Yes, I read it now and tried to edit my post as I can. Thank you for your answer but I couldn't understand you. Can you explain it? – AEnic31 Apr 07 '21 at 18:43
  • 2
    I highly recommend creating functions instead of macros. Let the compiler determine if inlining is appropriate. Functions give you type checking, macros don't. – Thomas Matthews Apr 07 '21 at 18:45
  • 1
    Macros may also be subject to substitution issues that functions don't. Remember, the macros are pasted into the code, *as-is*, before compilation begins. – Thomas Matthews Apr 07 '21 at 18:46
  • @ThomasMatthews thank you for the information. I am trying to learn C++ and I am new :) I even don't know how to create functions and use instead of macros. As soon as I learn, I will do as you say. – AEnic31 Apr 07 '21 at 18:49
  • BTW, refrain from using macros as abbreviations. Prefer to copy and paste as necessary. If you need to use macros as abbreviations, either take a keyboarding class or allow yourself more development time. – Thomas Matthews Apr 07 '21 at 19:21

1 Answers1

1

The infinite loop problem occurs because cin and underlying ifstream expects a float in your case. By not providing a float, cin fails and the weird loop occurs. More information here.

Since you cannot control the user and you do not want the program to break if the user inputs characters, you can read the input to string instead of float. This way, no error flag is set by cin.
Then, you should convert the string to float. atof is suitable for this purpose.

#include <iostream>
#include <string>
#include <cstdlib>
...
std::string epsilon_str;
std::cin >> epsilon_str;
double epsilon = atof(epsilon_str.c_str());

From the documentation of atof:

If the first sequence of non-whitespace characters in str does not form a valid floating-point number as just defined, or if no such sequence exists because either str is empty or contains only whitespace characters, no conversion is performed and the function returns 0.0.

Other general programming issues

  • There are lots of headers you include. Knowing what is required for which function or class is the best practice. I assume you included them when you needed, but if you won't use setprecision, then there is no reason to #include <iomanip>.

  • Using define means simply copy-paste. The compiler is not aware of what you are doing. See the following example.

    #define     WRONG_MULTIPLY(a, b)    a * b
    #define CORRECTED_MULTIPLY(a, b) ((a) * (b))
    ...
    int wrong_result     =     WRONG_MULTIPLY(1 + 2, 3 + 4); // 11
    int corrected_result = CORRECTED_MULTIPLY(1 + 2, 3 + 4); // 21
    

    The best practice is using functions. That is the purpose of functions.

    int multiply(int a, int b) {
        return a * b;
    }
    ...
    int result = multiply(1 + 2, 3 + 4);
    

    I used uppercase letters for macros to attract attention that they are macros. Seriously, you do not want to deal with compiler errors where the cause is a macro that you are not aware of.
    And at this point, I suggest going through a tutorial, like this one to understand the basic consepts.

  • It is advised not to use using namespace std;. If there exists an std::multiply with the same signature as of your function (same input-output), the standard one will be called without you noticing it. There are ways to prevent this but not knowing what happened is the problem in the first place. Let the compiler guide you and do not trick yourself.

  • The flow of the code and the uses of the labels seem complicated. Write code that you will understand, for example, two months later. I suggest breaking seperate functionalities into functions, like readFloat, checkEpsilonValid etc.

  • Declare variables when they are needed. This way it is easier to follow the code. Also, using meaningful variables instead of two-letter ones improves the readability and you do not even need to comment later.

  • Finally, be aware that setprecision affects cout throughout the program. It is about whether you care, but for bigger projects, I suggest using printf("%.06f"), or "%.06g", then flush if necessary.

Burak
  • 2,251
  • 1
  • 16
  • 33
  • Thank you very much for giving these really important informations. I am new in C++ and programming. I will be careful about these. – AEnic31 Apr 07 '21 at 21:55