Adding digits of a number than dividing by 9

Write your question here.
An integer is divisible by 9 if the sum of its digits is divisible by 9.
Develop a program to determine whether or not the following numbers are divisible by 9

i can not get the num to add to the total(combo) in the loop ffunction
it just crashes visual studio
I have tried many things but do not know what to do.
I assume that there is an error with my logic.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
 #include <iostream>
#include <string>
#include <cmath>
#include <cctype>
#include <cstdlib>
#include <iomanip>
using namespace std;

int div(string, char&, int&, int&);
int main()
{
	string data; // string is a number 
	char digit;// each individual digit
	int num; // digit converted to num
	int combo = 0; // adding each number to the total

	cout << "Enter in a number and i will determine if it is divisible by 9:";
	cin >> data;

	div(data, digit, num, combo);

	

	return 0;
}

int div(string data, char& digit, int& num, int& combo)
{
	int counter = 0;
	do
	{
		digit = data.at(counter); // get the first digit
		counter++; // counter goes up

		num = (int(digit) - int('0')); // convert digit to int

		cout << num << endl;
                   combo+= num ;  // adding each number to the total;

	} while (digit != ' '); // while we have not reached the end of the string

	return 0;
}
Last edited on
You should use std::string instead of char.
I do not understand what you mean. Plus that does not sound like it could work how would you change a string into ints,
closed account (D80DSL3A)
It may be crashing because there aren't any spaces in the string data and the terminal condition
while (digit != ' '); is never met.
Perhaps the condition while (counter < data.size() ); would work better.

I think your method should work, but there is a simpler method not involving strings or chars, just the int itself.
Last edited on
1
2
3
4
5
char& digit

. . .

 while (digit != ' '); // while we have not reached the end of the string 




I do not understand what you mean. Plus that does not sound like it could work how would you change a string into ints,
 
num = (int(digit) - int('0')); // convert digit to int 



???
I think your method should work, but there is a simpler method not involving strings or chars, just the int itself.

That will only work if the number is small enough to fit into an int. With this algorithm, the user should be able to enter a 200 digit number and get the correct answer, so I think strings are appropriate.

Andrewcen16
, fun2code is correct regarding your program crash. I suggest that you change the while loop to a for loop instead. For loops are great because all the "loopiness" code is in one place and all the "what to do in each iteration" is in another:
for (int counter = 0; counter < data.size(); ++counter) {
If you've learned about range-based for loops, then that would be even better:
for (digit : data) {

Now the only thing left is to determine and print the answer to the actual problem. So after the loop you will need to add code to decide if the sum-of-digits is divisible by 9 and print the answer.

num = (int(digit) - int('0')); // convert digit to int
The compiler will convert data types, so I think it's overkill to do it yourself. This line can be simply:
num = digit - '0';


There are several things you can do to make the code more modular. I suggest that you get it working first. Then if you're interested, ask about the structure and we can help you with that.
Last edited on
while (counter < data.size() ); would work better.
Thank you for the help. This was the line that was causing me all the trouble.

Could you help me make my code more modular?

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
#include <iostream>
#include <string>
#include <cmath>
#include <cctype>
#include <cstdlib>
#include <iomanip>
using namespace std;

int div(string, char&, int&, int&);
int main()
{
	string data; // string is a number 
	char digit;// each individual digit
	int num; // digit converted to num
	int combo = 0; // adding each number to the total

	cout << "Enter in a number and i will determine if it is divisible by 9:";
	cin >> data;

	div(data, digit, num, combo);
	cout << combo;


	return 0;
}

int div(string data, char& digit, int& num, int& combo)
{
	int counter = 0;
	do
	{
		digit = data.at(counter); // get the first digit
		counter++; // counter goes up

		num = (int(digit) - int('0')); // convert digit to int

		cout << num << endl;
		combo += num;  // adding each number to the total;

	} while (counter < data.size()); // while we have not reached the end of the string

	return 0;
}
Last edited on
dhayden wrote:
There are several things you can do to make the code more modular. I suggest that you get it working first. Then if you're interested, ask about the structure and we can help you with that.
I urge you to make these changes one at a time and test your program after each one. Then save the program to a different file and move on to the next change. All line numbers below refer to the original line in your last past unless otherwise stated.

1. The only include files you need are iostream and string so delete lines 3-6.

2.
Develop a program to determine whether or not the following numbers are divisible by 9

Your program doesn't really do that. It just prints out a bunch of numbers that the user must interpret. I suggest you change div to return a bool that says whether the number is divisible by 9:
- change line 9 to bool div(string, char &, int &, int &);
- change line 27 to bool div(string data, char& digit, int& num, int& combo)
- change line 42 to return (combo % 9 == 0);

3. Now that div returns a bool, you can output the right thing. Change lines 20 & 21 to
1
2
3
4
5
    if (div(data, digit, num, combo)) {
        cout << data << " is divisible by 9\n";
    } else {
        cout << data << " is not divisible by 9\n";
    }


4. Keep your data local. Variables digit, num and combo are only used in div(), so they should be declared there. This has the added benefit of needing fewer parameters in div:
- move lines 13-15 to right after line 29.
- Change line 9 to bool div(string);
- Change line 27 to bool div(string data)
- Change the call to div at line 1 in change number 3 above to if (div(data)) {

5. It's handy to think of loops as two different parts of code. There's the code that controls the loop, and the code that does something for each iteration. I like to use for loops whenever possible because they help to separate those two distinct bits of code. Look at div(): the code that controls the loop is at lines 29, 30, 33, and 40. It would be better to put all of that together:
1
2
3
for (int counter = 0; counter < data.size(); ++counter) {
...
}

If you've learned about range-based for loops, then it's even easier:
1
2
3
for (char digit : data){
...
}


As I mentioned earlier, let the compiler do the cast conversions for you so change line 35 to: num = digit - '0';. Better still, why have a separate digit variable at all? Get rid of digit and change line 35 to num = data[counter] - '0';

6. Line 37 is debugging code. Delete it.

7. Right now you're copying the string to div. That's wasteful. It would be better to pass a reference (or a const reference if you've learned about those). For a simple reference:
- change line 9 to bool div(string &);
- change line 27 to bool div(string &data)
> Could you help me make my code more modular?

Write many small functions, each one doing one thing, and doing it well.

Give one entity one cohesive responsibility.

Focus on one thing at a time: Prefer to give each entity (variable, class, function, namespace, module, library) one well-defined responsibility. As an entity grows, its scope of responsibility naturally increases, but its responsibility should not diverge.
...
Entities with disparate responsibilities are typically hard to design and implement. ... Prefer to build higher-level abstractions from smaller lower-level abstractions. Avoid collecting several low-level abstractions into a larger low-level conglomerate. Implementing a complex behavior out of several simple ones is easier than the reverse.

Alexandrescu and Sutter in 'C++ Coding Standards: 101 Rules, Guidelines, and Best Practices'


1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
#include <iostream>
#include <string>
#include <cctype>

// check if str contains a valid integer (without any leading + or -)
bool is_integer( std::string str )
{
    // return false if any character is not a decimal digit 
    // https://msdn.microsoft.com/en-us/library/jj203382.aspx
    for( char c : str ) if( !std::isdigit(c) ) return false ;

    return !str.empty() ; // return true if str contains at least one digit
}

// get a number entered by the user
std::string get_number()
{
    std::string data ;
    std::cout << "enter a decimal number without leading + or - : " ;
    std::cin >> data ;

    if( is_integer(data) ) return data ;
    
    // handle error in input
    std::cout << "that is not a valid decimal number. please try again\n" ;
    return get_number() ; // try again
}

// return the sum of all the digits in the integer
// invariant: is_integer(number) == true
int sum_digits( std::string number )
{
    int sum = 0 ;
    for( char c : number ) sum += c - '0' ;
    return sum ;
}

// invariant: is_integer(number) == true
bool is_divisible_by_nine( std::string  number )
{
    // true if sum of its digits is evenly divisible by 9
    return sum_digits(number) % 9 == 0 ;
}

int main()
{
    std::cout << "enter a number and i will determine if it is divisible by 9\n" ;
    const std::string number = get_number() ;

    std::cout << "the number " << number << " is " ;
    if( is_divisible_by_nine(number) ) std::cout << "divisible by nine\n" ;
    else std::cout << "not divisible by nine\n" ;
}
Topic archived. No new replies allowed.