Thread: N00b to C++ here, have some general questions.

  1. #16
    Deathray Engineer MacGyver's Avatar
    Join Date
    Mar 2007
    Posts
    3,210
    No, I meant for loops and while loops vs do-while loops. Not that there was such a thing as a for-while loop.... lol.....

    BTW, what about your program currently can't handle the n-digit scenario? You have a loop. It should work if your algorithm is correct (which I have some doubts about from looking at the loop).

  2. #17
    Kernel hacker
    Join Date
    Jul 2007
    Location
    Farncombe, Surrey, England
    Posts
    15,677
    Ok, so using for in the way MacGyver does is quite contrived (not that it's not a valid use, just that it's a bit "unusual" - a bit like using a screwdriver to open the tape on a box - not completely "strange", but not quite as neat as using a knife.

    If you really want to, you could solve it with (but I recommend AGAINST this):
    Code:
    for(;iX; iSumDump = iX % 10, iSum += iSumDump, iX /= 10);
    But I prefer either the do-while or while construction - the while construction also solves the case of a input value of zero not having to be calculated at all [not that it really matters in this case - but I always try to think about how to avoid executing code that isn't necessary to execute]
    Code:
    while(iX) {
       iSum += iX % 10;
       iX /= 10;
    }
    I removed the need for iSumDump, as it's not really necessary in this case. This is probably the simplest version (the same version can be done in a do-while loop of course, only differences is that iX is tested after the first iteration of the loop, rather than before).

    As for the n-digit scenario, if we assume that n is not larger than about 10 or so, you can still do it with integer numbers, same way you are doing right now.

    The only part I can see where you don't deal correctly with "any" number of digits is where you divide the number by 10000. Now, if you think about it, what method do you think you can use to find out what the most significant digit - perhaps some of your existing code already does that, of sorts...

    --
    Mats
    Compilers can produce warnings - make the compiler programmers happy: Use them!
    Please don't PM me for help - and no, I don't do help over instant messengers.

  3. #18
    Registered User
    Join Date
    Oct 2007
    Posts
    24
    I still haven't figured out the n-digit part, but I'll take care of it later. I was attempting to modify the program even more, for example, giving feedback when you enter a float I want my program to spew out "Invalid Input" or something similar. So basically, how would I check for floats? (The n-digit scenario here). I'd also appreciate it if the same could be done with character inputs (like abc34 or abed)

  4. #19
    Kernel hacker
    Join Date
    Jul 2007
    Location
    Farncombe, Surrey, England
    Posts
    15,677
    The best way to deal with validating input is to read a line of text and then verify that it can be converted correctly with no "leftovers".

    Use for example
    Code:
    std::string str;
    std::getline(cin, str);
    You can then validate that you can convert the string to a number, e.g.
    Code:
    #include <sstream>
    
    ...
       stringstream ss;
    
       ss << str;    // Fill the stringstream with the string entered.
    
       if (ss >> someint) {
         ... valid input ... 
       } else {
          ... input was not valid ... 
       }
    This doesn't attempt to recognise "not all of the input was consumed". This is much trickier to do, and I think it's not necessarily meaningfull to try to do that.

    --
    Mats
    Compilers can produce warnings - make the compiler programmers happy: Use them!
    Please don't PM me for help - and no, I don't do help over instant messengers.

  5. #20
    Registered User
    Join Date
    Oct 2007
    Posts
    24
    matsp, I'm sorry to say that what you said went way off the top of my head

    After a lot of googling, I came across this code chunk, but I've bolded and underlined parts that I don't get:

    Code:
    #include <iostream>
    #include <limits>
    
    using namespace std;
    
    int main() {
      int number = 0;
      cout << "Enter a integral value: ";
      cin >> number;
      cin.ignore(numeric_limits<int>::max(), '\n');
      if(number<0)
       {
         cout << "Error: You entered a negative number.";
         return 1;
       }
        
      if (!cin || cin.gcount() != 1)
        cout << "Not a numeric value.";
      else
        cout << "Your entered number: " << number;
        return 0;
    }
    Can someone help me understand what it does? Thanks a lot guys

    Edit: Oh I just noticed the new header file, lol. Now I should be off figuring out what that one does, lol

  6. #21
    Registered User
    Join Date
    Jan 2005
    Posts
    7,366
    That code isn't exactly complete, since it doesn't tell you how to clear the stream of errors and ask again. I prefer this method of checking for integers:
    Code:
    int number = 0;
    while (!(cin >> number) || cin.get() != '\n')
    {
        cin.clear();
        cin.ignore(numeric_limits<streamsize>::max(), '\n');
        // output your error message here and tell the user to try again.
    }
    Here's what it does
    Code:
    !(cin >> number)
    If cin fails to read in an int, it goes into a fail state. For example, if the user types characters like "abc", that isn't an int. Checking the return value allows you to check for the fail state. So if cin >> number fails, then it will evaluate to false and !(cin >> number) will be true. So if it fails, we'll enter the loop to clear the error and try again.
    Code:
     || cin.get() != '\n'
    If the input doesn't fail, then we check the next character. If the user types a number and hits enter, then it should be a newline, which is '\n'. If it is not a newline, then the user typed extra characters. So for example if the user types "123.0" or "123abc", this second part will be true and the code will enter the error handling loop.
    Code:
    cin.clear();
    This clears the failbit. If the loop was entered because the read failed, then this clears that flag so you can try to read again. If the fail bit is not set this does nothing, so it is safe to call here.
    Code:
    cin.ignore(numeric_limits<streamsize>::max(), '\n');
    This ignores all characters (up to the newline) in the buffer. It gets rid of all the bad input so the user can try again with a clean bluffer. You could also use int instead of streamsize, or even cin.ignore(1000, '\n');. The difference is that 1000 will ignore a maximum of 1000 characters, so if the user types in more than 1000 characters, they won't all be ignored. Using the numeric_limits version makes sure you ignore them all just in case.

    So overall, you try to read a number. If it fails or there are extra garbage characters, you clear and empty the cin stream and try again. You keep doing this in a loop until the user enters a number.

    Code:
    if (!cin || cin.gcount() != 1)
    In that code, the !cin is like the !(cin >> number) I used, it just checks cin later. The cin.gcount != 1 is like the cin.get() != '\n', it checks to make sure there is only one character (the newline) left in the stream.
    Last edited by Daved; 10-08-2007 at 11:53 PM.

  7. #22
    Registered User
    Join Date
    Oct 2007
    Posts
    24
    Oh man, I ran into so much trouble trying to come up with solutions as to why I couldn't just copy paste your code. Copy pasting is baaaaad, but in the end a lot of good came off of it as I knew more about what each part of each line does. Everything's uber fine now although it took me an hour to "perfectly adapt"

  8. #23
    Registered User
    Join Date
    Jan 2005
    Posts
    7,366
    Glad it's working.

    If you want you can post your final solution so others can benefit and in case there are any hidden gotchas we can point out.

  9. #24
    Registered User
    Join Date
    Oct 2007
    Posts
    24
    Sorry for the late reply . It'll be my pleasure to post it here.

    Code:
    #include <iostream> 
    #include <string>
    #include <limits>
    using namespace std;
    
    int main ()
    {
    	int iX = 0;
    	int iSmall;
    	int iBig;
    	int iY;
    	int iSmallestDigit = 9;
    	int iTestNum;
    	int iDigit;
    	int iLargestDigit = 0;
    	int iSum = 0;
    	int iSumDump;
    	int iZ;
    	char Check;
    
    	cout << "Class Information --"
    		 << "\n CIS 25 - ++ Programming"
    		 << "\n Laney College" << endl;
    
    	cout << "\nAssigment Information --"
    		 << "\n Assigment Number: Lab 03 Exercise #2"
    		 << "\n Written by: Amol Mundayoor"
    		 << "\n Due Date: 10/04/07" << endl;
    
    
    	do 
    	{
    	
    	cout << "\n\nEnter a 5-digit Integer (or -999999 to exit): ";
    	
    	while (!(cin >> iX) || cin.get() != '\n')
    	{
        
    		cin.clear();
    		cin.ignore(numeric_limits<int>::max(), '\n');
    		cout << " ERROR! Invalid input, please try again: ";
    	
    	}	
    
    
    	if (iX == -999999)
    			break;
    			
    	
    		if (iX &#37; 2 == 0)
    			{
    			cout << iX << " is an even ";
    			}
    		else
    			{
    			cout << iX << " is an odd ";
    			}
    		if (iX > 0)
    			{
    			cout << "and positive number\n";
    			}
    		else if (iX < 0)
    			{
    			cout << "and negative number\n";
    			}
    		else
    			{
    			cout << "Invalid Input" << endl;
    			}
    
    		iSmall = iX % 10;
    			cout << "The least significant digit is " << iSmall <<endl;
    
    		iBig = iX/10000;
    			cout << "The most significant digit is " << iBig << endl;
    
    		iTestNum = iX;
    			
    		do
    		{
    		
    		iDigit = iTestNum % 10;
    		
    		if ( iSmallestDigit > iDigit )
    			
    			{
    				iSmallestDigit = iDigit;
    			}
    		
    		iTestNum /= 10;
    		
    		} while ( iTestNum );
    	
    			cout << "Smallest Digit: " << iSmallestDigit << endl;
    		
    		iY = iX;
    
    		do
    		{
    		
    		iDigit = iY % 10;
    		
    		if ( iLargestDigit < iDigit )
    			
    			{
    				iLargestDigit = iDigit;
    			}
    		
    		iY /= 10;
    		
    		} while ( iY );
    	
    			cout << "Largest Digit: " << iLargestDigit << endl;
    
    		
    		iZ = iX;
    		iSum=0;
    		do
    		{
    			iSumDump = iZ % 10;
    			iSum = iSumDump+iSum;
    			iZ /= 10;
    		} while (iZ);
    			cout << "The sum of Digits is: "<< iSum << endl;
    
    		
    		cout << "\n\nWould you like to work with another value? Press [n] for No and [y] for Yes:";
    		cin >> Check;
    		
    	} while(Check == 'y' || Check == 'Y');
    
    
      return 0; 
    }
    .

    I've been reading, and I has a question. What's the difference between swap(); and void swap ();? If I write a code like this:

    Code:
     (a>b) ? a=b: swap();
    Does it do this:

    it checks if a is greater than b, and if it is, then it assigns the value of b to a, if not the values are swapped (what's in a goes to b, and what's in b goes to a). ? (I just figured out about the ternary conditional operator - I was testing if I knew how to use that too ). Thanks guys

    Edit:
    Oh, and is the above code (the single line one) the same as this:
    Code:
     (a>b) ? a=b: swap(a,b);
    Last edited by Bash; 10-13-2007 at 08:23 PM.

  10. #25
    C++ Witch laserlight's Avatar
    Join Date
    Oct 2003
    Location
    Singapore
    Posts
    28,413
    What's the difference between swap(); and void swap ();?
    I have no context to work with, but "swap();" is probably a call to some function named swap that takes no arguments (or allows no arguments and uses default arguments instead). "void swap();" is the prototype of a function named swap that takes no arguments and does not return a value.

    it checks if a is greater than b, and if it is, then it assigns the value of b to a, if not the values are swapped (what's in a goes to b, and what's in b goes to a). ?
    Probably not. It depends on what exactly this swap() function actually does, and whether a and b are member variables etc... but most likely you are trying to call a function that does not exist. The swap() function template from <algorithm> takes two arguments by reference and swaps them, assuming that they are of a type that is copy constructible and copy assignable.

    So, your second version has the right idea, but this is not the place to use the ternary operator. Instead, write:
    Code:
    if (a > b)
    {
        a = b;
    }
    else
    {
        swap(a, b);
    }
    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

  11. #26
    Registered User
    Join Date
    Oct 2007
    Posts
    24
    Well our prof had asked this question in class:

    (1) Given that the following prototypes are given in some program. What would and may be potential problems from each of the following function prototypes (declarations)?
    Code:
    void swap( int, int );
    void swap( int = 1, int = 1 );
    void swap( int*, int* );
    void swap( int&, int& );
    void swap( int&, int* );
    And I'm clueless. I know that if there's a void before a function, it doesn't return anything. Beyond that I don't know much.

  12. #27
    Deathray Engineer MacGyver's Avatar
    Join Date
    Mar 2007
    Posts
    3,210
    Depends on your prof's definition of "potential problems". There are reasons to pass a straight int vs a pointer to an int vs a reference to an int, etc. etc..

  13. #28
    Registered User
    Join Date
    Oct 2007
    Posts
    24
    Well my trouble is I just don't know what exactly those void swap( ); thingy does. If used correctly, what is it supposed to do?

  14. #29
    Deathray Engineer MacGyver's Avatar
    Join Date
    Mar 2007
    Posts
    3,210
    You pick one to define the function a certain way. The first one takes two ints. The rest take something else.... either references or pointers. It all depends upon what you want to do.

  15. #30
    Cat without Hat CornedBee's Avatar
    Join Date
    Apr 2003
    Posts
    8,895
    The potential problem between the first two is that one has default parameters and the other doesn't, which can be misleading in various situations. (It wouldn't be allowed to give both of the default parameters, so the one without should be removed.)

    The potential of the first two in general is that they'll have a hard time swapping their values, given that they take them by value.

    The third one works.

    The fourth one works, too, but is hidden by the first two if you pass variables.

    The last one probably works, too, but it completely unintuitive.
    All the buzzt!
    CornedBee

    "There is not now, nor has there ever been, nor will there ever be, any programming language in which it is the least bit difficult to write bad code."
    - Flon's Law

Popular pages Recent additions subscribe to a feed

Similar Threads

  1. Password program / general programming questions
    By plr112387 in forum C++ Programming
    Replies: 13
    Last Post: 11-04-2007, 10:10 PM
  2. n00b questions
    By C+noob in forum C++ Programming
    Replies: 43
    Last Post: 07-09-2005, 03:38 PM
  3. A Few General C Questions
    By Jedijacob in forum C Programming
    Replies: 13
    Last Post: 02-17-2005, 02:47 AM
  4. Taking up OpenGL(extreme n00b questions)
    By Xterria in forum Game Programming
    Replies: 3
    Last Post: 03-26-2004, 04:49 PM
  5. FAQ: Examples of good questions (General)
    By Prelude in forum FAQ Board
    Replies: 1
    Last Post: 10-11-2002, 08:57 PM