#include<iostream>
#include<conio.h>
#include<time.h>
#include<windows.h>
#include<math.h>
#include <string.h>
#include <sstream>

using namespace std;

int main()
{   int result = 1;
    float checker; //Holds the full array
    char char_holder;
    int loop = 0;
    float checker2 = 0; //gets the letter
    float checker3 = 0; //Holds the previous array
    int counter;
    int x = 0;
    char name = 'A';
    double Dresult;
    char Cresult[10] = {'\0','\0','\0','\0','\0','\0','\0','\0','\0','\0'};
 do{
    printf("\n Enter value for %c ", name);
    cin>>Cresult;
    
            for (x = 0; Cresult[x] != '\0' ; x++) //Cresult[x] != Null Terminator
              {   
                  if (x != 0)
                 {checker3 = checker;}
                  char_holder = (int)Cresult[x];
                  checker2 = atof(&char_holder);

                  if (x == 0) //if its the first one start adding onto it  
                     {  checker3 = checker2;
                        checker = checker2;
                     
                      }
                  else
                  {checker2 /= 10;
                   checker = (checker + checker2)*10;
                     Sleep(1000);
                        if(checker > 2147483647)
                          { cout<<"Overflow error....2\n";
                          Sleep(2000);
                          result = 0;
                          Dresult = 0;
                          for (x = 0 ; Cresult[x] != '\0' ; x++) //Cresult[x] != Null Terminator
               {
                   Cresult[x]= '\0';} 
                          break;
                          }
                         else if(checker < checker3)
                         { cout<<"Overflow error....1";
                         Sleep(2000);
                         Dresult = 0;
                         result = 0;
                         break;
                         }
                         //else { checker3 = checker;}
                   }
                     cout<<"Checker: "<<checker<<"\t";
                     cout<<"Checker2: "<<checker2<<"\t";
                     cout<<"Checker3: "<<checker3<<"\t"<<'\n';
                     Sleep(10);
               }  
               if (Dresult != 0)
               {
               Dresult = atoi (Cresult);
               }
               cout<<"\n\n";
               cout<<"Cresult: "<<Cresult<<'\n';
               cout<<"Dresult: "<<Dresult<<'\n';;
               Sleep(1000);
               for (x = 0 ; Cresult[x] != 0 ; x++)
               {
                   Cresult[x]= '\0';} 
               
               cout<<Cresult;
               checker = 0;
               checker2 = 0;
               checker3 =0;
               Dresult = 0;
               Sleep(1000);
               }
               while(loop == 0);
               return 0;
               }

Attention: This is something I was messing around with for hours, I don't expect it to look picture perfect, right now I just want the idea working before i clean it up.

This is an isolated part of code from a bigger calculator I'm working on. My teacher enjoys breaking our programs in any way possible, so I'm trying to show him up by making it unable to be broken. In my original project I have it setup to use a process similar to this in order to recieve the number inputted by the user. In the original project I use isdigit to check if theyre inputting characters where theyre inputting numbers so thats why i have the input orginally saved as a string in order to do so. In order to check for overflow i have it set up so that it manually adds on each number until it reaches overflow (overflows an int) then it breaks out and resets. If you input 21 it will output 21, if you input 999999999999, itll overflow and work properly, but once i start having 999999999999999999999999999(enough to fill up 2 - 3 lines of my console. It out puts 1.#INF without adding up the numbers, outputs overflow(which is good) it resets everything(which is good), but once it reaches the end of the program it crashes. I have no idea how to stop it from doing so besides it just being unecessary for me to input so much. A friend of mine doesnt have the fix for characters, so if you input fsdfsdf21, it wil break, but for his if you spam 9's it outputs 1.#INF, but continues to run (He accepts the input as an INT). I don't know if anyone will know what the problem is =/.

Recommended Answers

All 7 Replies

Can you take the input as a string and then check the length. If it is more than say 10 characters you can output "please don't input such large numbers" or something.

There is still overflow. When building an intermediate value, it is safest to stop before the least significant digit of the largest possible value, then you can test the intermediate value and next digit separately for overflow.

#include <cctype>
#include <climits>
#include <iostream>

int main()
{
    const unsigned safe_value = INT_MAX / 10;
    const unsigned last_digit = INT_MAX % 10;

    unsigned long temp = 0;
    char c;

    std::cout << "Enter a positive integer: ";

    while (std::cin.get(c) && std::isdigit(c)) {
        unsigned curr_digit = c - '0';

        if (temp > safe_value || 
            (temp == safe_value && curr_digit > last_digit))
        {
            std::cerr << "Overflow!\n";
            break;
        }

        temp = 10 * temp + curr_digit;
    }

    std::cout << "Converted value: " << temp <<'\n';
}

This is the best way Edward can think of for avoiding overflow without restricting the value's range.

> If it is more than say 10 characters you can output "please don't input such large numbers" or something.
It would need to be 10 characters or more, because most of the values in the 10 digit range overflow a 32 bit int. But that limits the range of possible values for input.

I like the idea that both of you have given me but, ive been trying to look for a way to do a proper check of the length of the character array, I tried your code out Edward and I like what it does, only problem is that if i spam 2 rows of 9's it seems to break regardless, Im thinking the problem is that in order to check it it has to be saved, so to hold back such spam it has to be checked as it is inputted, but If i tried it that way id have to worry about allowing the person to backspace and such and i dont know if the effort would be worth it for it to not run the way it should. Is there a way I can either put the spam into the array and then check the size and change it accordingly right after, or just defaulty delete all input or just not accept any input past 10 characters?

Maybe load the input into a string using getline and then parse using Edward's algorithm?

#include <cctype>
#include <climits>
#include <iostream>
#include <string>

int main()
{
    const unsigned safe_value = INT_MAX / 10;
    const unsigned last_digit = INT_MAX % 10;

    std::string line;

    std::cout << "Enter a positive integer: ";

    if (getline(std::cin, line)) {
        std::string::const_iterator c = line.begin();
        unsigned long temp = 0;

        while (c != line.end() && std::isdigit(*c)) {
            unsigned curr_digit = *c - '0';

            if (temp > safe_value || 
                (temp == safe_value && curr_digit > last_digit))
            {
                std::cerr << "Overflow!\n";
                break;
            }

            temp = 10 * temp + curr_digit;
        }

        std::cout << "Converted value: " << temp <<'\n';
    }
}

If the problem is spam, either do not allow characters after overflow, like Ed's first sample, or allow spam but do not process it after overflow.

I like Edwards new algorithm but now if i just enter 9 it automatically changed it from 9 to 99999999 and called it overflow. I am currently trying to do cin.getline(Cresult,10) it works the first time, but when i try to the same function again in my calculator it just doesn't let me input anything, I have an error saying if it isnt a number to cout<<"A problem has occured", whenever i try to load the function again it just gives me that message. I tried resetting all variables i have when it runs through the fucntion again, but something overwrites me inputs, so im wondering if its the rest of the spam that was leftover is being thrown into the input, How do i clear that from my program?

> now if i just enter 9 it automatically changed it from 9 to 99999999 and called it overflow.
Ed's mistake. The iterator is never incremented. Replace this line

unsigned curr_digit = *c - '0';

with this line

unsigned curr_digit = *c++ - '0';

I like the way this works, Thanks Ed(Gj sounding like Cowboy Bebop :P). Ill fiddle around with it tomorrow, if i dont know what something means i might ask a few things. Thanks again :)

Be a part of the DaniWeb community

We're a friendly, industry-focused community of developers, IT pros, digital marketers, and technology enthusiasts meeting, networking, learning, and sharing knowledge.