Thread: do while loop question

  1. #1
    Registered User
    Join Date
    Feb 2018
    Location
    San Diego, CA
    Posts
    111

    do while loop question

    Hey all, i've just a quick question with my getNumbeAndBase() function. The program being executed is not continuing to the convertNumber() function after for example, "Number to be converted: 2001" and a number in valid range between "2 & 16" the loop just asks for another number to be converted but gives the correct response when a number smaller than 2 or larger then 16 is inputted, therefore the correct and working if statement. Please only comment on noted function not rest of the program. This was worked out of a programming book. Thanks.

    Code:
    // Program to convert a positive integer to another base
    
    
    
    
    #include <stdio.h>
    #include <stdlib.h>
    
    
    int		convertedNumber[64];
    long int	numberToConvert;
    int		base;
    int		digit = 0;
    
    
    void	getNumberAndBase (void)
    {
    	do {
    		printf("Number to be converted? ");
    		scanf("%li", &numberToConvert);
    
    
    		if(numberToConvert == 0)
    		{
    			exit(1);
    		}
    
    
    		do {
    			printf("Base? ");
    			scanf("%i", &base);
    			{
    				if(base < 2 || base > 16)
    				{
    					printf("Bad base - must be between 2 and 16\n");
    				}
    			}
    		} while (base < 2 || base > 16);
    	} while (numberToConvert != 0);
    }
    
    
    void	convertNumber (void)
    {
    	do {
    		convertedNumber[digit] = numberToConvert % base;
    		++digit;
    		numberToConvert /= base;
    	}
    	while (numberToConvert != 0 );
    }
    
    
    void	displayConvertedNumber (void)
    {
    	const char baseDigits[16] =
    	{ '0', '1', '2', '3', '4', '5', '6', '7',
    		'8', '9', 'A', 'B', 'C', 'D', 'E', 'F' };
    	int	nextDigit;
    
    
    	printf("Converted number = ");
    
    
    	for(--digit; digit >= 0; --digit ) {
    		nextDigit = convertedNumber[digit];
    		printf("%c", baseDigits[nextDigit]);
    	}
    
    
    	printf("\n");
    }
    
    
    int main (void)
    {
    	void getNumberAndBase (void), convertNumber (void), displayConvertedNumber (void);
    
    
    	getNumberAndBase ();
    	convertNumber ();
    	displayConvertedNumber ();
    
    
    	return 0;
    }

  2. #2
    C++ Witch laserlight's Avatar
    Join Date
    Oct 2003
    Location
    Singapore
    Posts
    27,511
    Quote Originally Posted by _jamie
    Please only comment on noted function not rest of the program. This was worked out of a programming book.
    Why, because you're afraid people will criticise you for unnecessarily using global variables, issit?

    So let's start with that first: make your functions easier to reason about by getting rid of all the global variables. Yes, turn all four of them into local variables that you pass as arguments and/or return from the functions.

    This way, it would become clear what's the input and output of getNumberAndBase, and from there you might find that it would be better to break up getNumberAndBase into two functions (getNumber and getBase) that each do one thing and do it well.

    Also, since you will be checking for the validity of the user input within the loop body anyway, the do while loops might not be quite so useful as you're just repeating the check. It's possible to write another function that will check the validity and return a boolean value to indicate it, and if so you can then call this function in the condition of the do while loop. But if you prefer to keep the check in the body of the function, a controlled infinite loop (i.e., for with empty condition or while (1)) that you manually break out of could be better.

    EDIT:
    Quote Originally Posted by _jamie
    The program being executed is not continuing to the convertNumber() function after for example, "Number to be converted: 2001" and a number in valid range between "2 & 16" the loop just asks for another number to be converted but gives the correct response when a number smaller than 2 or larger then 16 is inputted, therefore the correct and working if statement.
    That's related to my point about not repeating the validity check: notice that the validity check for the first user input in the loop body and the one in the loop condition are different.
    Last edited by laserlight; 09-24-2019 at 01:14 PM.
    Quote Originally Posted by Bjarne Stroustrup (2000-10-14)
    I get maybe two dozen requests for help with some sort of programming or design problem every day. Most have more sense than to send me hundreds of lines of code. If they do, I ask them to find the smallest example that exhibits the problem and send me that. Mostly, they then find the error themselves. "Finding the smallest program that demonstrates the error" is a powerful debugging tool.
    Look up a C++ Reference and learn How To Ask Questions The Smart Way

  3. #3
    Registered User
    Join Date
    Feb 2018
    Location
    San Diego, CA
    Posts
    111
    Thanks for the time and effort on the last response laserlight. I was able to fix my problem by using the while (1) the break'ing out of the loop, works fine now. The global variables I completely missed but were copied from the programming book.

  4. #4
    misoturbutc Hodor's Avatar
    Join Date
    Nov 2013
    Posts
    1,740
    Quote Originally Posted by _jamie View Post
    Thanks for the time and effort on the last response laserlight. I was able to fix my problem by using the while (1) the break'ing out of the loop, works fine now. The global variables I completely missed but were copied from the programming book.
    May we see the new code? I'm just asking because I would not (necessarily) have fixed the issue by changing to a while(1) loop and using a break (edit: but I'm not entirely clear which loop you changed to that form)

  5. #5
    Registered User
    Join Date
    Feb 2018
    Location
    San Diego, CA
    Posts
    111
    Hodor: here's the code with the infinite while loop:

    Code:
    // Program to convert a positive integer to another base
    
    
    
    
    #include <stdio.h>
    #include <stdlib.h>
    
    
    int		convertedNumber[64];
    long int	numberToConvert;
    int		base;
    int		digit = 0;
    
    
    void	getNumberAndBase (void)
    {
    	while (1)
    	{
    		printf("Number to be converted? ");
    		scanf("%li", &numberToConvert);
    
    
    		if(numberToConvert == 0)
    		{
    			exit(1);
    		}
    		do {
    			printf("Base? ");
    			scanf("%i", &base);
    			if(base < 2 || base > 16)
    			{
    				printf("Bad base - must be between 2 and 16\n");
    			}
    		} while (base < 2 || base > 16);
    		break;
    	}
    }
    
    
    void	convertNumber (void)
    {
    	do {
    		convertedNumber[digit] = numberToConvert % base;
    		++digit;
    		numberToConvert /= base;
    	}
    	while (numberToConvert != 0 );
    }
    
    
    void	displayConvertedNumber (void)
    {
    	const char baseDigits[16] =
    	{ '0', '1', '2', '3', '4', '5', '6', '7',
    		'8', '9', 'A', 'B', 'C', 'D', 'E', 'F' };
    	int	nextDigit;
    
    
    	printf("Converted number = ");
    
    
    	for(--digit; digit >= 0; --digit ) {
    		nextDigit = convertedNumber[digit];
    		printf("%c", baseDigits[nextDigit]);
    	}
    
    
    	printf("\n");
    }
    
    
    int main (void)
    {
    	void getNumberAndBase (void), convertNumber (void), displayConvertedNumber (void);
    
    
    	getNumberAndBase ();
    	convertNumber ();
    	displayConvertedNumber ();
    
    
    	return 0;
    }

  6. #6
    misoturbutc Hodor's Avatar
    Join Date
    Nov 2013
    Posts
    1,740
    Quote Originally Posted by _jamie View Post
    Hodor: here's the code with the infinite while loop:

    [/code]

    Ok, I found the book you've gotten the general code from, but it doesn't use functions. So you're refactoring the program (that I see listed as program 6.7) so that it uses functions. I think that's a good idea, but you need to go a step further and stop using the global variables, as suggested by laserlight. One problem that immediately jumps out is that you can only every call displayConvertedNumber() once (unless in between calls you call convertNumber() again). This is just one problem. E.g.

    Code:
    int main (void)
    {
        void getNumberAndBase (void), convertNumber (void), displayConvertedNumber (void);
     
     
        getNumberAndBase ();
        convertNumber ();
        displayConvertedNumber ();
        displayConvertedNumber ();
     
     
        return 0;
    }
    will display (as an example)

    Code:
    Number to be converted? 16
    Base? 2
    Converted number = 10000
    Converted number =
    Clearly this is not desirable and can be remedied by not using global variables. Changing things to avoid those globals will also make your code easier to read. I would have thought by chapter 6 of the book things like functions would already have been covered, but I don't have the book so am not sure.

    Edit: Ok, I see your program is actually from listing 8.14 of the book in a section talking about global variables. What a horrible program and explanation of global variables. Maybe skip that part of the book. Also, listing the function prototypes for the functions (void getNumberAndBase (void), convertNumber (void), displayConvertedNumber (void) inside main() isn't a common practice.
    Last edited by Hodor; 09-24-2019 at 06:57 PM.

Popular pages Recent additions subscribe to a feed

Similar Threads

  1. Can't do this question using while or for loop
    By Zuri786 in forum C Programming
    Replies: 5
    Last Post: 10-06-2017, 01:09 AM
  2. Replies: 3
    Last Post: 09-22-2016, 09:08 AM
  3. Question about For (Loop)
    By lyn88 in forum C Programming
    Replies: 2
    Last Post: 09-30-2010, 09:37 PM
  4. Loop question
    By kwood965 in forum C Programming
    Replies: 6
    Last Post: 10-29-2008, 11:12 PM
  5. Loop question
    By Jas11 in forum C++ Programming
    Replies: 31
    Last Post: 04-28-2005, 07:16 PM

Tags for this Thread