Still celebrating National IT Professionals Day with 3 months of free Premium Membership. Use Code ITDAY17

x
?
Solved

Need help with a while loop using cin.peek()

Posted on 2004-03-29
6
Medium Priority
?
1,555 Views
Last Modified: 2007-12-19
I need help finding some logic errors. My program is getting stuck in the two while loops. This program takes two numbers and then formats the output to scientific notation. Here is the first part of my code. Any help would be greatly appreciated!

int main()
{
      double x, y;

      x = readNum();
      y = readNum();
      //printFormatted( x, y );

      return 0;
}

double readNum()
{
      
      double num = 0;
      double place = 10;
      char numb[20];
      cout << "Enter a number: ";
      cin.get(numb, 20);

      while (cin.peek() != '.' || cin.peek() != '\n')
            num *= static_cast<double>(cin.get() ) + 10;
            
      while (cin.peek() != '\n') {
            num += static_cast< double >( cin.get() ) / place;
            place *= 10;
      }
      
      cin.ignore();
      return num;
}
0
Comment
Question by:AndyCV6
[X]
Welcome to Experts Exchange

Add your voice to the tech community where 5M+ people just like you are talking about what matters.

  • Help others & share knowledge
  • Earn cash & points
  • Learn & ask questions
6 Comments
 
LVL 15

Assisted Solution

by:lakshman_ce
lakshman_ce earned 80 total points
ID: 10709951
I couldn't understand why you are using cin.peek() here. cin.peek() prompts for entry by user

Just try this..code for reading two numbers

double readNum()
{
   
     double num = 0;
     double place = 10;
     cout << "Enter a number: ";
     num *= static_cast<double>(cin.get() ) + 10;
     num += static_cast< double >( cin.get() ) / place;
     place *= 10;      
     cin.ignore();
     return num;

}
Please refer to for using cin.peek()
http://www.experts-exchange.com/Programming/Programming_Languages/Cplusplus/Q_20789094.html

-Lakshman
0
 

Author Comment

by:AndyCV6
ID: 10710245
I am trying to learn about cin.peek(). Is there any reason why that it would not work like I have it? Doesn't cin.peek() look at each character? In the first loop, I want it to look at each character and stop when it comes to a '.' or a newline. My end result from this program should be two numbers formated like so:
x is +2.346000000
y is      8.95e-001

I will check out that link you gave me and see if that helps.

Thanks
0
 
LVL 15

Assisted Solution

by:efn
efn earned 200 total points
ID: 10710405
I was going to advise you not to use peek until I saw your last comment.

The call to get leaves the terminating newline character in the input stream, so if the next loop is terminated by a newline character, it will end before it reads anything.

It's not advisable to call peek twice in the same expression, because you could get different results each time if input appeared between the two calls.  This is just a fine point, not likely to be a problem in your testing.

The first while loop will run as long as peek returns something that is either not a period or not a newline.  What could peek return that would cause the loop to end?  If it's a period, it's not a newline, so the loop still runs.  If it's a newline, it's not a period, so the loop still runs.

The call to get consumes the first line input, not including the newline character.  You as the user must know that after you enter a number and press Enter, you still have to enter another number and press Enter again.  Perhaps you were doing that.

The American Standard Code for Information Interchange, commonly known as "ASCII" specifies a correspondence between the numeric values of characters and the character representation used in input and output with humans.  For example, the character '1' has a numeric value of 49.  When you cast a character to double, you get the numeric value.  For example, a '1' character will give you a double value of 49.0.  This is probably not what you want.  A simple way to convert a digit character to the corresponding numeric value is to subtract '0' from it.  This doesn't work so well with characters that are not digits, so industrial-strength software would check for that possibility.

num is initialized to zero.  The first loop attempts to multiply it by input numbers.  Since zero times anything is zero, this is unlikely to change the value of num.

--efn
0
Concerto's Cloud Advisory Services

Want to avoid the missteps to gaining all the benefits of the cloud? Learn more about the different assessment options from our Cloud Advisory team.

 

Author Comment

by:AndyCV6
ID: 10711081
ok, i read the info from the link, and what  efn posted. I made some changes to my code. It will now break out of the loops but, my output is still not right. I am not sure what to do about initializing num. Let me post all of my code for this program.

#include <iostream>

using std::cout;
using std::endl;
using std::cin;
using std::ios;

#include <iomanip>

using std::setw;
using std::setprecision;
using std::resetiosflags;
using std::setfill;
using std::setiosflags;

double readNum();
void printFormatted( double, double );

int main()
{
      double x, y;

      x = readNum();
      y = readNum();
      printFormatted( x, y );

      return 0;
}

double readNum()
{
      double num = 0;
      double place = 10;
      cout << "Enter a number: ";

      while (cin.peek() != '.' && cin.peek() != '\n')
            num *= static_cast< double >( cin.get() ) + 10;
      //cin.ignore();
      
      while (cin.peek() != '.') {
            num += static_cast< double >( cin.get() ) / place;
            place *= 10;
      }
       cin.ignore();
       return num;
}

void printFormatted( double x, double y )
{
      char buffer[] = "The value of x is: ";
       for( int i = 0; buffer[ i ] != '\0'; i++ )
             cout.put( buffer[ i ] );

       cout << setprecision( 3 ) << setfill( '0' )
             << setiosflags( ios::fixed | ios::showpos )
             << setiosflags( ios::left ) << setw( 12 ) << x << endl;

       cout.write( "The value of y is: ", 21 );
       cout << resetiosflags( ios::showpos )
             << setprecision( 3 )
             << setiosflags( ios::scientific | ios::right )
             << y << endl;
}

0
 
LVL 15

Assisted Solution

by:efn
efn earned 200 total points
ID: 10711367
The last two bugs I described are still there.

If you are trying to build up a number by reading its digits from left to right, each time you get a new digit, you should multiply what you had so far by 10 and then add the digit.  So you want something like this:

number = (number * 10) + digit;

What you have (if you fix the casting-to-double bug) is:

number *= digit + 10;

This is equivalent to

number = number * (digit + 10);

The problem is not initializing num to zero.  The problem is the calculation.

--efn
0
 
LVL 39

Accepted Solution

by:
itsmeandnobodyelse earned 220 total points
ID: 10712645
As efn has told you the calculation (and loop conditions) were wrong. Try this.

double readNum()
{
     double num = 0;
     double place = 10;
     char   digit;

     cout << "Enter a number: ";

     while ((digit = cin.peek()) != '.' && digit != '\n')
     {
         if (digit < '0' || digit > '9')
         {
             cout << "Invalid digit " << digit << endl;
             exit(1);
         }
         // eat digit
         cin.get();
         num = num * 10. + (digit - '0');
     }

     if (digit == '.')
     {
         // eat period
         cin.get();

         while ((digit = cin.peek()) != '\n')
         {
             if (digit < '0' || digit > '9')
             {
                 cout << "Invalid digit " << digit << endl;
                 exit(2);
             }
             // eat digit
             cin.get();
             num += (digit - '0') / place;
             place *= 10;
         }
     }
     cout << "Valid number is " << num << endl;
     cin.ignore();
     return num;
}

Regards, Alex

0

Featured Post

How to Use the Help Bell

Need to boost the visibility of your question for solutions? Use the Experts Exchange Help Bell to confirm priority levels and contact subject-matter experts for question attention.  Check out this how-to article for more information.

Question has a verified solution.

If you are experiencing a similar issue, please ask a related question

Written by John Humphreys C++ Threading and the POSIX Library This article will cover the basic information that you need to know in order to make use of the POSIX threading library available for C and C++ on UNIX and most Linux systems.   [s…
This article shows you how to optimize memory allocations in C++ using placement new. Applicable especially to usecases dealing with creation of large number of objects. A brief on problem: Lets take example problem for simplicity: - I have a G…
The viewer will learn how to clear a vector as well as how to detect empty vectors in C++.
The viewer will be introduced to the member functions push_back and pop_back of the vector class. The video will teach the difference between the two as well as how to use each one along with its functionality.

661 members asked questions and received personalized solutions in the past 7 days.

Join the community of 500,000 technology professionals and ask your questions.

Join & Ask a Question