Thread: Moving around in functions

  1. #1
    Registered User
    Join Date
    Mar 2010
    Location
    Australia
    Posts
    174

    Moving around in functions

    I have this simple situation where I call a void function within another function:

    Code:
    void prompt() {
        char command = '\0';
        int numScanned = 0;
        
        printf("? ");
        numScanned = scanf("%c", &command);
        
        while (numScanned == 1) {
            if (command == 'h') {
                helpCommand();
            }
            
            printf("? ");
            numScanned = scanf("%c", &command);
        }
        
    }
    Basically the program will query the user with

    ?

    and then it will expect a character to be entered. If the character is equivalent to h then it will call a void function called helpCommand which is just a function that prints stuff. The problem however is that when I run the program I'm getting the results

    ? h
    <helpCommand output>
    ? ?

    notice the double question marks, or even if I input something other than h I get

    ? a
    ? ?

    which is clearly happening because it's printing the second question mark within the while loop and then somehow it's going back to the beginning of the prompt function and printing the first question mark? I'm really confused about this, and I've also checked to see what is in the character variable command after the scanf in the while loop and it doesn't print out anything (or it's possibly a space, blank, etc.).

    Can anyone please explain what is happening here?

  2. #2
    C++ Witch laserlight's Avatar
    Join Date
    Oct 2003
    Location
    Singapore
    Posts
    28,413
    The newline from entering the input was left in the input buffer and then read by the next scanf call.
    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

  3. #3
    Registered User
    Join Date
    Sep 2012
    Posts
    357
    You don't just press 'h', do you? I'm pretty sure you also press ENTER just after the 'h'.

    You need to ignore the ENTER:
    Code:
    if (command == '\n') /* do what is needed to ignore ENTER */
    You may also want to ignore space, TAB, and any other special characters ...

  4. #4
    Registered User
    Join Date
    Mar 2010
    Location
    Australia
    Posts
    174
    I was unsure of how to ignore the enter, so I've done it in a crude way

    Code:
    void prompt() {
        char command = '\0';
        int numScanned = 0;
        
        printf("? ");
        numScanned = scanf("%c", &command);
        printf("command = %c\n", command);
        
        while (numScanned == 1) {
            if (command == 'h') {
                helpCommand();
            }
            printf("? ");
            while (command == '\n' || command == ' ' || command == '\t') {
                numScanned = scanf("%c", &command);
            }
            numScanned = scanf("%c", &command);
        }
        
    }
    Yet it's still not working, and I'm already seeing a problem with this because later on I'm going to need to accept a newline from the user (as opposed to h or any other character I'll also be using). Also, I'm unsure with what other characters can be used besides new lines, spaces and tabs.

    EDIT: What I've written clearly doesn't work either. It scans until it finds something other than those blank characters and then it waits to scan again.

    EDIT2: Ok I have it working:

    Code:
    void prompt() {
        char command = '\0';
        int numScanned = 0;
        
        printf("? ");
        numScanned = scanf("%c", &command);
        printf("command = %c\n", command);
        
        while (numScanned == 1) {
            if (command == 'h') {
                helpCommand();
            }
            printf("? ");
            numScanned = scanf("%c", &command);
            while (command == '\n' || command == ' ' || command == '\t') {
                numScanned = scanf("%c", &command);
            }
        }
    }
    I still have the problem that I'll need to accept a newline character from the user at some point, but I guess I can cross that bridge when I get there.
    Also, is it possible to make this more succinct? I find it hard to believe that I need 3 scanfs to just do the one task of scanning.
    Last edited by Mentallic; 09-11-2012 at 09:00 AM.

  5. #5
    Registered User
    Join Date
    Nov 2010
    Location
    Long Beach, CA
    Posts
    5,909
    You can't make it too much more succint, but, since you're using scanf only to read one char, you could just call getchar. It amounts to the same thing and is probably more clear. In general, I find scanf a pain for user input, and it gets really ugly if you mix it with fgets, etc.

    Basically, what you're trying to do is flush the input buffer, i.e. discard everything upto and including a new line. Read this FAQ article we have: FAQ > Flush the input buffer - Cprogramming.com.

    I suggest making a function that flushes the input buffer so you can reuse it everywhere.

  6. #6
    Registered User
    Join Date
    Mar 2010
    Location
    Australia
    Posts
    174
    Ok, thankyou. I'll look into that.

  7. #7
    Been here, done that.
    Join Date
    May 2003
    Posts
    1,164
    Here's a more 'concise' version
    Code:
    void prompt() 
    {
        char command = '\0';
        
        printf("? ");
        command = getchar();
        printf("command = %c\n", command);
        
        while (command != exitcharacter)  
        {
            while (xx = getchar() != '\n') ;        // discard the rest of the buffer
    
            if (command == 'h') 
            {
                helpCommand();
                continue;                               // skip rest of the loop
            }
            // process other characters
    
    
            printf("? ");
            command = getchar();
        }
    }
    Definition: Politics -- Latin, from
    poly meaning many and
    tics meaning blood sucking parasites
    -- Tom Smothers

Popular pages Recent additions subscribe to a feed

Similar Threads

  1. moving valuables from classes to functions and back to beginning
    By military genius in forum C++ Programming
    Replies: 0
    Last Post: 10-08-2009, 06:54 PM
  2. moving functions into visual compilers
    By pastitprogram in forum C++ Programming
    Replies: 4
    Last Post: 09-03-2008, 06:37 AM
  3. Moving from C to C++
    By tweeres04 in forum C++ Programming
    Replies: 50
    Last Post: 05-05-2006, 07:58 AM
  4. moving over from C
    By PING in forum A Brief History of Cprogramming.com
    Replies: 6
    Last Post: 09-11-2005, 08:52 AM
  5. moving around in C
    By Unregistered in forum C Programming
    Replies: 1
    Last Post: 11-02-2001, 08:20 AM