OK PEOPLE I NEED HELP AGAIN........pls dont do my homework..........thats y i havnt given the question this time aroung :)


the question im asking is simple :

the program asks user to input product id ( a,b,c,d or e) and its quantity sold......it then saves total sale in "int sale"

but y doesnt the "do while" loop terminate upon entering "\r" (enter)

#include <iostream.h>
#include <conio.h>
#include <iomanip.h>
int main()
	{
   float A=7.98,B=3.22,C=5.59,D=8.71,E=2.33;     //prices of products
   char ch;                                                    //identity of product
   int sold;                                                     //no. of sold product  
   float sale=0;                                                //total sale

   do{
   cout<<"\n Enter product code( a,b,c,d,e ),followed by quantity of product sold"<<endl;
   cout<<" Or press Enter twice for total"<<endl;

   cin>>ch>>sold;

   switch (ch)
   	{
      case 'a':
      sale=+A*sold;
      break;

      case 'b':
      sale=+B*sold;
      break;

      case 'c':
      sale=+C*sold;
      break;

      case 'd':
      sale=+D*sold;
      break;

      case 'e':
      sale=+E*sold;
      break;

      default:
      cout<<"Invalid product"<<endl;

      }
      }while ( ch != '\r' || sold!='\r');

   cout<<"\n Total sales equal"<<sale;

   getch();
   return 0;
   }

Dani AI

Generated

Root cause (short): the input extraction operator (operator>>) skips whitespace, so pressing Enter does not produce a '\r' or '\n' value for ch or sold — the stream simply waits for the next non-whitespace token. That explains 's “two enters” observation and matches 's point about >> stopping on whitespace. The loop condition while (ch != '\r' || sold != '\r') is doubly wrong: comparing an int to '\r' is a type-mismatch, and || makes the test almost always true; if a sentinel test were wanted the logic would need to be different (and easier designs exist).

A robust pattern is line-oriented input: read a whole line, test whether the line is empty (treat that as “done”), then parse the code and quantity from the line. This both detects blank lines reliably and avoids trying to read a non-numeric sentinel into the quantity variable. Example approach:

#include <iostream>
#include <string>
#include <sstream>
#include <unordered_map>
#include <cctype>

int main() {
    std::unordered_map<char,double> price = {{'a',7.98},{'b',3.22},{'c',5.59},{'d',8.71},{'e',2.33}};
    double total = 0.0;
    std::string line;
    while (true) {
        if (!std::getline(std::cin, line)) break;
        if (line.empty()) break;
        std::istringstream iss(line);
        char code; int qty;
        if (!(iss >> code >> qty)) { std::cout << "Bad input\n"; continue; }
        code = std::tolower(static_cast<unsigned char>(code));
        auto it = price.find(code);
        if (it == price.end()) { std::cout << "Unknown code\n"; continue; }
        total += it->second * qty;
    }
    std::cout << "Total sales: " << total << '\n';
}

Extra notes and fixes: replace sale =+ A * sold; with sale += A * sold; to accumulate. If a single-character sentinel is preferred, read the code first and check it before attempting to read the quantity (that avoids trying to parse 'X' into an integer — the mistake suggested to “fix” by casting is not a safe solution). std::getline plus istringstream simplifies validation, makes the UI predictable, and removes dependence on platform newline details that led to the original confusion. References: , , and offered pieces of this reasoning; the line-based approach combines those pieces into a safe, practical solution.

Recommended Answers

All 9 Replies

because you need to enter 2 newlines before the condition is false.

when you enter just 1, ch will have been read but the program is still waiting for input to the sold parameter.
Only when that's filled as well will loop processing commence.
When at the end of the loop both are found to contain \r the loop will terminate.
When there's only 1 \r, one of the conditions of the while will be false and the other true.
true || false == true as is false || true.
Only false || false results in false.

Run the program in a debugger if you wish to confirm this :)

>but y doesnt the "do while" loop terminate upon entering "\r" (enter)
cin's >> operator terminates on whitespace. \r and \n are whitespace, so ch and sold will never have those values, the program will simply sit there waiting for input until it gets something it likes.

this doesnt help either;

do{
.
.
.
cout<<" Or input X and X for total"<<endl;
.
.
.
.
.
while ( ch != 'X' || sold!='X');

>this doesnt help either
ch is a char, but sold isn't. cin doesn't know that they're technically interchangeable and X will fail miserably when read by cin for sold. I think your problem is that you don't have a good idea of what the user interface should be, so you end up floundering about for anything that works, no matter how silly, and you make mistakes.

Humor me and try this: Figure out exactly how you want the user interface to work to the point where you can describe it precisely, with examples. Then we'll go from there. I can guarantee that with the proper design foundation, the program will be much better.

I think you understand do...while loops. However, your problem lies in your use of C++ console input.

The getch(char ch) function always skips whitespaces. This includes <space>, <tab>, and <newline>, which, unfortunately, you are relying on to terminate your input loop.

The '\r' character, along with ' ', '\n', '\t', etc., will never be assigned to your "ch" or "sold" variables, so your test will never quit.

You do have options, though:

1. Use a function that does not skip whitespace, such as get.ch(char ch) from the <iostream> library. There is a caveat, however; you will now be capturing whitespace, and you must manually skip over spaces and such from the user.

2. Use a sentinel value in your loop. This means you use a dummy value, such as 'q' for quit, to indicate that the user wants to stop input.

I feel for you; C++ console input is HARD! But, you can do it, even if you don't use one of these suggestions. Just think about what you want the user to input, and design your code accordingly, just like Narue said to do.

THANX ALOT PPL!!!!!!!!!!................


......narue for poiting out that X cannot be stored in float :o


.....thehap for suggesting valuable alternatives!!!! :cheesy:

Dear do this

do{
...
...
cin>>ch;
cin>>sold;
...
...
}while(ch!='\r' && (char)sold!='\r');
//sold is an integer typecast as character here then u will not got any warning.
//ok try this one

>//sold is an integer typecast as character here then u will not got any warning.
You have no idea what you're talking about, do you?

>//ok try this one
Try it if you want, it won't work, as I explained in detail above. If you had bothered to read it (or even try your own suggestion) then you wouldn't have been stupid enough to suggest something so blatantly incorrect.

You will not be adding up your total with something like =+ the correct operator is +=

Unless you have to use double return key, I would go with something as simple as t1 and flag down the 't' character to exit the loop.

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.