Thread: If Loop Not Working?

  1. #1
    Registered User
    Join Date
    Nov 2013
    Posts
    18

    If Loop Not Working?

    Alright, I need the code read the user input, tell how many white spaces it skipped over, how many characters there were, and the ending character. HOWEVER, I also need to display an error message if the user enters something other than an integer first:
    EX:
    56* is okay,
    *56 is not okay.

    <space><space>4 is okay
    .........4 is not okay.

    here's my code so far:

    Code:
    #include <stdio.h>
    
    int
    main ()
    {
      int mainInteger = 0;
      printf ("\nEnter an integer: ");
      miniScanf ();
      printf ("\nMain's integer (printed with a %%d) is now %d \n\n",
              mainInteger);
    }
    
    
    int
    miniScanf (int mainInteger)
    {
      int blanks = 0;
      int characterCount = 0;
      char lastChar;
      char error;
      char firstChar;
    
      scanf("%c", &mainInteger);
      firstChar = mainInteger;
    
      while (mainInteger != '\n')
        {      
          scanf ("%c", &mainInteger);
          characterCount++;
          while (mainInteger == ' ')      //To count the white spaces.
            {
              scanf ("%c", &mainInteger);
              blanks++;
              characterCount++;
            }
    
          if (firstChar < 48 || firstChar > 57 || firstChar != 32)     //ASCII codes for 0-9 and ' '. To produce the error.
            {             
              if (mainInteger == '\n')
                {  
                  printf
                    ("\nError, scan terminated by non-whitespace, non-digit before any digits encountered.\n");
                  printf ("\nSkipped over %d characters of white space.\n\n",
                          blanks);
                  printf
                    ("Stopped scanning after %d characters (including the leading whitespace, if any), last character that stopped the scan was a '%c' (0x%x).\n",
                     characterCount - 1, error, error);
                  return;
                }    
            }                
    
    
          if (mainInteger == '\n')        //To end after user presses enter key.
            {
              printf ("\nSkipped over %d characters of white space.\n\n", blanks);
              printf          
                ("Stopped scanning after %d characters (including the leading whitespace, if any), last character that stopped the scan was a '%c' (0x%x).\n",
                 characterCount - 1, lastChar, lastChar);
              return;
            }
          else             
            {
              lastChar = mainInteger;
            }
        }              
    }
    Input/Output:
    Enter an integer: 56*

    Error, scan terminated by non-whitespace, non-digit before any digits encountered.

    Skipped over 0 characters of white space.

    Stopped scanning after 2 characters (including the leading whitespace, if any), last character that stopped the scan was a '' (0x0).

    Main's integer (printed with a %d) is now 0
    Ignoring the obvious problem that the scan was not stopped with a space, but with a *, and that main's integer should now be 56, why is it displaying this error message when the user entered an integer first? I'm not allowed to use string.h or scanf anything other than as a character.

    As always, help is most appreciated.

  2. #2
    Algorithm Dissector iMalc's Avatar
    Join Date
    Dec 2005
    Location
    New Zealand
    Posts
    6,318
    Think carefully about line 37. Only one of the three part of it needs to be true to execute the following statements. The last one is particularly easy to be true.

    Also, there is no such thing as an "if loop".
    My homepage
    Advice: Take only as directed - If symptoms persist, please see your debugger

    Linus Torvalds: "But it clearly is the only right way. The fact that everybody else does it some other way only means that they are wrong"

  3. #3
    Registered User
    Join Date
    Nov 2012
    Posts
    1,393
    If you want to refer to the numeric codes for '0' and '9' or any other character, you can just write them in the code:

    Code:
    if (firstChar < '0' || firstChar > '9' || firstChar != ' ')
    To solve your original problem (formatted input), you can write a scanf format string and then check the return value which scanf gives. This will tell you if all of your input was consumed or not. For example if you want the input to contain 2 spaces followed by an integer, you would use this format string:

    "%c%c%d"

    The return value should be 3 if all of it was consumed.
    Last edited by c99tutorial; 11-23-2013 at 10:02 AM.

  4. #4
    Registered User
    Join Date
    Mar 2010
    Posts
    583
    Code:
    if (firstChar < '0' || firstChar > '9' || firstChar != ' ')
    This is clearer but it has the same problem. iMalc already said it. In your "58*" example, firstChar is '5'.

    So look at the above condition. Is '5' valid? is it less than '0'? No. Is it greater than '9'? No. Is it not equal to ' '? Yes. Only one condition needs to be true, so '5' is treated as being incorrect.

    What you mean here is "must be between 0 and 9 or be whitespace". Currently you have "must be between 0 and 9 and be whitespace".
    Code:
    if ((firstChar < '0' || firstChar > '9') && firstChar != ' ')
    Meaning "if it's either less than zero or more than nine, AND it's not a whitespace, it's wrong".

    Just a couple of minor points:
    • Your character count at the end is always one char short because you don't increment characterCount when you first read into mainInteger.
    • Your mainInteger printf in main() will already print zero, because you're not returning it from your function or passing a pointer to it. C always passes arguments by value, so changing mainInteger in miniScanf doesn't affect the variable in main.


    Althuogh looking a bit more, I don't get what mainInteger's purpose is. It'll always contain '\n'. If you intend to use it as a return value, I'd suggest not using it as a temporary throughout the function -- it's the wrong type for %c scanfs (gcc checks this, but I know not all compilers do). You'll get away with it if you make sure the rest of the int is always 0 -- but why not just use a char?
    Last edited by smokeyangel; 11-23-2013 at 01:09 PM.

  5. #5
    Registered User migf1's Avatar
    Join Date
    May 2013
    Location
    Athens, Greece
    Posts
    385
    Why not using isspace(), isdigit(), etc instead of ascii codes ?

    On a side note, the problem is a bit vague to me. For example what should happen when the input includes trailing spaces, or both leading & trailing spaces?

    Also, do non-digits following digits invalidate the computed integer? For example, with a valid input "56*" should we compute the returned integer as 56 or not?

    Furthermore, does a leading non-digit, non-space character cause an early exit, or the total count of characters in the input should be reported?

    PS. Is this a homework?

Popular pages Recent additions subscribe to a feed

Similar Threads

  1. Loop stops working when loop >45 ??
    By Zul56 in forum C Programming
    Replies: 3
    Last Post: 12-11-2012, 03:40 PM
  2. While loop isn't working
    By jburn09 in forum C Programming
    Replies: 2
    Last Post: 09-19-2012, 11:47 AM
  3. Can't get do while loop working
    By FernandoBasso in forum C Programming
    Replies: 8
    Last Post: 10-05-2011, 06:36 PM
  4. while() loop isn't working right..
    By Captain Penguin in forum C++ Programming
    Replies: 20
    Last Post: 10-03-2002, 10:29 PM

Tags for this Thread