HELP PROJECT DUE IN AN HOUR

The user is required to enter a character to represent the package chosen. If a
character other than ('A', 'a', 'B', 'b', 'C', 'c') is entered, the program provides a
message and re-prompts them for a new package selection. The program will
continue to prompt the user until a valid package is chosen. Assume the user will
only enter a single character; there is no need to error check for entries of multiple
characters.

^^^ that's what I have to do when they input a package that's not valid but when they input it wrong more than once it jumps to the next line of code, what do I do? i.e. it jumps to the unit codes instead of redoing package

if (package != 'a' && package != 'A' && package != 'b' && package != 'B' && package != 'c' && package != 'C')

{
cout << "Please enter only A, B, or C." << endl;
cin >> package;
}

cout << "Enter the number of message units (1 - 672)\n";
cin >> units;

if (units < 1 || units > 672)
{
cout << "Please enter a number between 1 and 672" << endl;
cin >> units;
Last edited on
Just write edit the if-statment as so: if (tolower(package) < ('a') || tolower(package) > ('c'))
Don't forget to #include <cctype>

or you can take input like this:
1
2
3
4
5
6
7
do {
cout << "Which package are you shopping for?\n";
cout << "Enter 'a' or 'A' for package A.\n";
cout << "Enter 'b' or 'B' for package B.\n";
cout << "Enter 'c' or 'C' for package C.\n";
cin >> package;
} while (tolower(package) != 'a' && tolower(package) != 'b' && tolower(package) != 'c');


Btw the return 0; that you've written in your if-statement will exit the program. Remove the return statement if that's not your intention.
Last edited on
Thank you! I figured this out from another person's post, but how do I get that to repeat if they keep inputting wrong variables? When I test it, it just jumps to the next line of code instead of redoing the package code.
Try the do-while statement.
Call the tolower function once, investigate the switch statement inside a while . Provide a quit option that uses a bool. Provide a default case also.

I have a personal dislike for statements like this:


if (package != 'a' && package != 'A' && package != 'b' && package != 'B' && package != 'c' && package != 'C')

they are UGLY and non scalable.

Just because a do statement always executes at least once shouldn't be a sole motivation for using it IMO.
Just because a do statement always executes at least once shouldn't be a sole motivation for using it IMO.
@TheIdeasMan, genuine question: what other motivations are there for using a do-statement?

Forcing function-like macros to have to end in semi-colons :D
1
2
3
4
5
6
7
8
9
10
// Example program
#include <iostream>

#define PRINT_A_THING(x) do { std::cout << (x) << '\n'; } while (0)  

int main()
{
    //PRINT_A_THING(42) // error!
    PRINT_A_THING(42); // ok!
}

Note: I'm not really being serious, please don't do this unless Linus Torvalds tells you to.
Last edited on
please don't do this

Don't worry, that's what lambdas are for! ;-)
#define PRINT_A_THING(x) ([]{ std::cout << (x) << '\n'; }())

But I jest. Point's taken. (Better stick a __FILE__ in there somewhere so there's an excuse!)
By the way TheIdeasMan, I initially used tolower() only once, but the OP's code treated a, b, c and A, B, C differently (he edited that out now, but they had different prices) that's why I changed it like I did.

If you weren't to use do-while then you would have to initialize the variable 'package' and use while, both are fine but I find initializing unnecessary.
Last edited on
what other motivations are there for using a do-statement?

I find this handy sometimes, although one should also consider whether RAII or throwing an exception is more appropriate:

1
2
3
4
5
6
7
8
9
10
11
12
13
doStuff();
do {  // while false
    blahBlahBlah;
    if (condition1) break;
    yadayadayada;
    if (condition2) break;
    boogieWoogieOogie;
    if (condition3) break;
} while false;
doLots();
ofCommon();
cleanup();
code();

It's often cleaner than stuffing the cleanup code in place of each of the breaks.

mbozzi wrote:
@TheIdeasMan, genuine question: what other motivations are there for using a do-statement?



The example in K&R is copying a C style string, the null must be placed at the end even if the string is empty.

K&R also mention they find do statements error prone, and rarely used. However a while loop may cost an extra variable.

TheIdeasMan wrote:
The example in K&R is copying a C style string, the null must be placed at the end even if the string is empty.

Code example, please
> Code example, please

K&R, second edition:
Experience shows that do-while is much less used than while and for. Nonetheless, from time to time it is valuable, as in the following function itoa, which converts a number to a character string (the inverse of atoi). The job is slightly more complicated than might be thought at first, because the easy methods of generating the digits generate them in the wrong order. We have chosen to generate the string backwards, then reverse it.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
/* itoa: convert n to characters in s */
void itoa(int n, char s[])
{
    int i, sign;

    if ((sign = n) < 0) /* record sign */
        n = -n; /* make n positive */

    i = 0;
    do { /* generate digits in reverse order */
        s[i++] = n % 10 + '0'; /* get next digit */
    } while ((n /= 10) > 0); /* delete it */

    if (sign < 0)
        s[i++] = '-';
    s[i] = '\0';
    
    reverse(s);
}

The do-while is necessary, or at least convenient, since at least one character must be installed in the array s, even if n is zero. We also used braces around the single statement that makes up the body of the do-while, even though they are unnecessary, so the hasty reader will not mistake the while part for the beginning of a while loop.
JLBorges I appreciate it. That's a neat example. But I wonder what TheIdeasMan was talking about with his quoted example.
technically that c-string while loop is the same thing though. Execute one time regardless of condition.

The comment was
Just because a do statement always executes at least once shouldn't be a sole motivation for using it IMO.


And the example given … executes at least once so it can stuff the null char into a c-string.


Maybe this is a terminology or hair splitting thing, but I am still unconvinced that do-while has a use outside of the execute once capability.


you don't even need an extra variable for this one, to use while, lol.

cstring[0] = 0; //no extra var

while(whatever)
{ modify cstring etc}

in practice, when I used c-strings, I typically had a pattern of using a for loop up front and using the loop index variable (which was not scoped to the loop for this reason) as the location to append the zero after the loop.
int I;
for(I = 0; condition; I++)
code;
cstring[I] = 0; //problem solved.


Last edited on
Okay I get it, didn't realize I had to go back to front.
1
2
3
4
5
6
7
8
9
10
11
const int size = 5;

char array1[size];
char array2[size] = "Hell";

int index = --size;

do {
   array1[size] = array2[size];

} while (--size != -1);


By the way, would you rather use a while loop and have to initialize the input variable like TheIdeasMan or use a do-while (open question to anybody).

edit: But wait it's the same as
1
2
3
4
 while (size != -1) {
   array1[size] = array2[size]
   --size;
}


So.. no I don't get it :'(
Last edited on
closed account (E0p9LyTq)
A while loop is NOT the same as a do/while loop. A do/while loop is executed at least one time even if the test condition is false.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
#include <iostream>

int main()
{
   int someArray[10];

   int index = -5;

   do
   {
      std::cout << "Index: " << index << '\n';

      someArray[index];  // OOOPS!  out-of-bounds!
   } while (index >= 0 && index < 10);
}

vs.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
#include <iostream>

int main()
{
   int someArray[10];

   int index = -5;

   while (index >= 0 && index < 10)
   {
      std::cout << "Index: " << index << '\n';

      someArray[index];
   }
}
What I meant was the 'result' is the same as size never begins with - 1 in the first place, so I'm not sure what TheIdeasMan was talking about. That code snippet was a guess.
Topic archived. No new replies allowed.