Thread: User input y/n questions.

  1. #1
    Registered User
    Join Date
    Oct 2008
    Posts
    5

    User input y/n questions.

    Hello,
    I am not massively competent at programming, so please comment as much as you feel is appropriate.

    I am designing a complex impedance circuit with several components. Basically I want to ask the user if they want to replace a certain component with a different one.

    Something like

    printf("Do you want to replace either capacitor 1, or 2 with a CPE? (y/n)\n");
    getchar()?? fgets, strings??

    I dont know which to use. I need it to loop somehow, so that if other characters/numbers are entered other than y/n, then it re-asks the question.

    I know this is probably annoying simple. But i have scoured the internet, but they seem to use something like while (getchar != '\n'), i dont know why this is needed...does getchar read a return as a \n. I've also read things about using two getchars???

    I just want it to work and be reasonably bullet proof.

    Thank you ever so much for any help you can offer me.

  2. #2
    and the hat of int overfl Salem's Avatar
    Join Date
    Aug 2001
    Location
    The edge of the known universe
    Posts
    39,659
    Using fgets() to read the whole line, then parsing that line for your expected information will be the easiest to make robust in the long run.

    It will also have the fewest surprises when it comes to keeping the input stream in a consistent state.
    If you dance barefoot on the broken glass of undefined behaviour, you've got to expect the occasional cut.
    If at first you don't succeed, try writing your phone number on the exam paper.

  3. #3
    Registered User C_ntua's Avatar
    Join Date
    Jun 2008
    Posts
    1,853
    Ok, here is an example with fgets():
    Code:
    #define MAX_INPUT 1024
    
    char buffer[MAX_INPUT];
    fgets(buffer,MAX_INPUT,stdin);
    Now, fgets will read everything from the standard input (stdin) thus the console until the '\n' is found or MAX_INPUT characters are read. It will store everything in buffer. It will also store the '\n' character.
    In any case, you have two approaches.
    1) Read only the first char. Thus "yes", "yahoo", "yeah" would all means yes. "No", "neh" will mean No. Anything else will be invalid and the have to type again.
    2) They have to enter only one character.

    I ll give an example with the first approach.
    Code:
    #define MAX_INPUT 1024
    
    char buffer[MAX_INPUT];
    while (fgets(buffer,MAX_INPUT,stdin) != NULL) {
        if (buffer[0] == 'y' || buffer[0] == 'Y') {
            doYes();
            break;
        } else if ((buffer[0] == 'n' || buffer[0] == 'N') {
            break;
        } else {
            printf("Enter (y/n)\n");
        }
    }
    Now, fgets reads the input, saves it to buffer and then you do whatever you want. If neither Y,y,N,n is pressed then the process is repeated. The != null exists just in case there is an error from fgets() in which case NULL is returned.
    If the user enters more than MAX_INPUT characters then the result is undefined, but it wont crash or overflow. You can check that also, but I don't think you really care at the moment

  4. #4
    C++まいる!Cをこわせ!
    Join Date
    Oct 2007
    Location
    Inside my computer
    Posts
    24,654
    It's better to do:
    Code:
    #define MAX_INPUT 1024
    
    char buffer[MAX_INPUT];
    while (fgets(buffer, MAX_INPUT, stdin) != NULL)
    {
        buffer[strlen(buffer) - 1] = '\0'; // Truncate newline
        buffer[0] = toupper(buffer[0]);
        if (strcmp(buffer, "Y") == 0)
        {
            doYes();
            break;
        }
        else if (strcmp(buffer, "N") == 0)
        {
            doNo();
            break;
        }
        else if (strcmp(buffer, "Q") == 0)
             break;
        else
            printf("Enter (y/n) or q to quit\n");
    }
    Last edited by Elysia; 10-26-2008 at 02:38 PM.
    Quote Originally Posted by Adak View Post
    io.h certainly IS included in some modern compilers. It is no longer part of the standard for C, but it is nevertheless, included in the very latest Pelles C versions.
    Quote Originally Posted by Salem View Post
    You mean it's included as a crutch to help ancient programmers limp along without them having to relearn too much.

    Outside of your DOS world, your header file is meaningless.

  5. #5
    Registered User
    Join Date
    Oct 2008
    Posts
    5
    Omg, you are a life-saver. Thank you so much....Ive been hammering against this for hours. I've got loads of switch functions working but for such a simple things its actually reasonably complicated.

    I've got a few questions.
    How would you achieve the NULL, what could force that to happen?
    Is buffer[0] the first character of the string?
    What does 'doYes()' do? Does it send the user to a new part of code?
    What does buffer[strlen(buffer)] = '\0'; do exactly? Please be really verbose.
    The code (strcmp(buffer, "Y") == 0), compares the characters in string buffer, to the letter Y, and checks if its == 0. Why would it be == 0. Is a value of 0 returned, if buffer contains a Y?

    Thank you very much.
    Last edited by phufbq; 10-26-2008 at 02:34 PM.

  6. #6
    Woof, woof! zacs7's Avatar
    Join Date
    Mar 2007
    Location
    Australia
    Posts
    3,459
    There are a few major flaws in Elysia's code.

    There may or may not be a newline character; you could be destroying the last character that you may want. See the FAQ on how to avoid this, (uses strchr).

    BUFSIZ also exists for a reason, perhaps use it .

  7. #7
    C++まいる!Cをこわせ!
    Join Date
    Oct 2007
    Location
    Inside my computer
    Posts
    24,654
    Quote Originally Posted by phufbq View Post
    How would you achieve the NULL, what could force that to happen?
    fgets returns NULL if an error occurs. Likely if you press Ctrl+C on Windows, for example.

    Is buffer[0] the first character of the string?
    Yes. Always.

    What does 'doYes()' do? Does it send the user to a new part of code?
    It's a function call and it was put there as a placeholder for whatever code you wanted to do if the user answers yes.

    What does buffer[strlen(buffer)] = '\0'; do exactly? Please be really verbose.
    strlen(buffer) will returns the length of the string. That is the first part.
    A string in C always ends with a '\0' character. So strlen searches the string until it finds it and then returns the length. All other string functions also work on the same principle.
    Since fgets reads the entire line including the newline, your buffer is going to look like:
    y\n
    So we want to get rid of that newline.
    The newline will always be at the end of the buffer. The last character.
    So to find it, we first calculate the length.
    In this case, strlen will return 2.
    So the index where the \n is located will be 1 (since index starts at 0).
    We replace the '\n' with a '\0', which basically cuts off the string at that point. The new string will look like:
    y

    The code (strcmp(buffer, "Y") == 0), compares the characters in string buffer, to the letter Y, and checks if its == 0. Why would it be == 0. Is a value of 0 returned, if buffer contains a Y?
    strcmp compares the two strings you provide as arguments and returns < 0, 0 or > 0 depending on how they match or differ. It returns 0 if the strings are equal.
    It does not compare to a letter. Using strcmp prevents people from entering Yessir instead of just Y.
    Using C_ntua's method, people can enter pretty much anything they want, so long as it starts with Y, N or Q, because it would only compare the first character.
    My method compares the entire string.

    Quote Originally Posted by zacs7 View Post
    There are a few major flaws in Elysia's code.

    There may or may not be a newline character; you could be destroying the last character that you may want. See the FAQ on how to avoid this, (uses strchr).
    Although, if I'm not mistaken, if you read from the console, it will always contain a newline. I took this into account, but I realize there are other ways.
    Regardless, as a C++ dev, I do not really practice these methods, so I used the one I know.
    Quote Originally Posted by Adak View Post
    io.h certainly IS included in some modern compilers. It is no longer part of the standard for C, but it is nevertheless, included in the very latest Pelles C versions.
    Quote Originally Posted by Salem View Post
    You mean it's included as a crutch to help ancient programmers limp along without them having to relearn too much.

    Outside of your DOS world, your header file is meaningless.

  8. #8
    Registered User
    Join Date
    Oct 2008
    Posts
    5
    Hello I've integrated your code into my work. But i've got a bit of a problem with the looping.
    This while statement is in the main function. When I answer 'Y' to the question and supply the right infomation, it starts asking me to input y or n again. How do i get out of the while loop and return to the main function, once the infomation (C_1, and n_value) have been got.

    *ADDITION* I've solved. I missed out a couple of vital breaks, needed. I've put them into the code now.

    Code:
    while (fgets(answer,sizeof(answer),stdin) != NULL)
    	{
    	answer[strlen(answer)] = '\0'; /* Truncate newline*
    	answer[0] = toupper(answer[0]);
    		if (answer[0] == 'Y')
    		{
    			printf("What value of C in nF do you want?\n");
    			scanf("&#37;lf", &C_dummy);
    			C_1 = C_dummy / 1000000000;
    			printf("What value of n would you like between -1 and 1?\n");
    			scanf("%lf", &n_value);
    			do {
    			if (n_value < 1 && n_value > -1)
    			{
    				continue;
    			}
    			else
    			{
    				printf("The value of n you inputted was not between the range, please try again.\n");
    				scanf("%lf", &n_value);
    			}
    			} while (n_value > 1 || n_value < -1);
                           break;
    		}
    	        else if (answer[0] == 'N')
    		{
    			printf("You chose N.\n");
                           break;
    		}
    		else
    		{
    			printf("Please enter either y or n.\n");
    		}
    	}
    Last edited by phufbq; 10-27-2008 at 09:43 AM.

  9. #9
    C++まいる!Cをこわせ!
    Join Date
    Oct 2007
    Location
    Inside my computer
    Posts
    24,654
    You do not need to truncate the newline if you are only going to compare the first letter.
    Furthermore, it should be strlen(answer) - 1. It was a bug that I corrected in an edit.
    Quote Originally Posted by Adak View Post
    io.h certainly IS included in some modern compilers. It is no longer part of the standard for C, but it is nevertheless, included in the very latest Pelles C versions.
    Quote Originally Posted by Salem View Post
    You mean it's included as a crutch to help ancient programmers limp along without them having to relearn too much.

    Outside of your DOS world, your header file is meaningless.

Popular pages Recent additions subscribe to a feed

Similar Threads

  1. can someone help me with these errors please code included
    By geekrockergal in forum C Programming
    Replies: 7
    Last Post: 02-10-2009, 02:20 PM
  2. About aes
    By gumit in forum C Programming
    Replies: 13
    Last Post: 10-24-2006, 03:42 PM
  3. Structure and Linked List User Input Question
    By kevndale79 in forum C Programming
    Replies: 16
    Last Post: 10-05-2006, 11:09 AM
  4. SSH Hacker Activity!! AAHHH!!
    By Kleid-0 in forum A Brief History of Cprogramming.com
    Replies: 15
    Last Post: 03-06-2005, 03:53 PM
  5. Nested Structures - User Input
    By shazg2000 in forum C Programming
    Replies: 2
    Last Post: 01-09-2005, 10:53 AM