C++ cin can't read in integers with 0 in them

2.8k views Asked by At

I was on hackerrank, and I ran into a very weird problem. The problem is "You are given an integer N. Find the digits in this number that exactly divide N (division that leaves 0 as remainder) and display their count. For N=24, there are 2 digits (2 & 4). Both of these digits exactly divide 24. So our answer is 2.". Here is my solution:

#include <cmath>
#include <cstdio>
#include <vector>
#include <iostream>
#include <algorithm>
using namespace std;

int main() {
/* Enter your code here. Read input from STDIN. Print output to STDOUT */
    int t, count;

    cin >> t;
    for (int i = 0; i < t; i++) {
        int n, copy;
        cout << "i: " << i << " ";
        cin >> n;
        cout << "n: " << n << " ";
        copy = n;
        count = 0;
        while (copy > 0) {
            if (n % (copy % 10) == 0)
                count++;
            copy = copy/10;
        }
        cout << "\n" << count << "\n";
    }  
    return 0;
}

t is the number of test cases, and n is the number to be tested. I can input any number I want into t without problems. However, if I input a number with a zero into n, I get a floating point exception error. The error occurs before the second cout statement. Other numbers work fine (so, for instance, 1024 gives an error, but 1124 is fine). I ran this code on the hackerrank website. Can someone please explain what is going on?

4

There are 4 answers

5
Joseph Hutchinson On BEST ANSWER

You can't mod divide by 0. Try to redesign your algorithm so that you avoid trying to perform that operation. Perhaps check copy % 10 == 0 then just skip that case. The reason that it is a floating point exception and not a divide by zero exception is described in this stack exchange post

0
coryknapp On

You can't mod something by 0. Check to make sure copy is nonzero.

1
bashrc On

Floating point exception usually occurs when attempting to do an illegal arithmetic operation. (Check this) In your example you will end up doing modulo 0 which is undefined behaviour. Most runtimes will bail out with some kind of runtime error. Here is the output that gdb gives on running your code with following input:

1 10

Program received signal SIGFPE, Arithmetic exception.
0x0000000000400920 in main () at a.cpp:21
21              if (n % (copy % 10) == 0)

Try remodelling your algorithm so that you do not end up doing that.

(I would suggest learning debugging tools and running your code through them to catch such issues)

Regarding why the line was not printed, that's because most implementations of cin and cout are buffer based (Read this for more on buffered i/o). Had you added a "std::endl" after cout you could have seen the output coming. Or you could have used std::cerr for outputting debug info. std::cerr has more stringent requirements laid down by the standard to flush more diligently. In your case before the buffer could be flushed the application terminated.

0
Aditya Shekhawat On

Your code will work just fine when you enter any no. without any 0 digit in it .The problem in your code is that you are trying to divide the number by 0.

       **if (n % (copy % 10) == 0)**

In this when we enter any no with 0 as a digit then the value of (copy%10) becomes 0.Thus it tries to divide n by 0 thus throwing an floating point exception error. Change your code like this :

Declare a new variable named 'r'.This will prevent execution of the command when we get 0 as a digit.Thus the program will run just fine

while(copy!=0)
        {`enter code here`
            r=copy%10;
            if(r!=0)
            {
                if(n % r==0)
                count++;
            }
            copy=copy/10;
        }
        cout<<count<<endl;