1

If I only want the user to enter one char, how would I go about doing that in the c language. My attempt at this is below but it failed horribly. From what i read online I heard you could use the function gets or fgets to accomplish this, but I could not figure out how.

do
{
    geussNumber += 1;
    printf("Enter guess number %d\n", geussNumber);
    scanf(" %c", &geussLetter);
    scanf ("%c", &inputViolation);
        if (isalpha(geussLetter) == 0)
        {
            printf("You did not enter a letter\n");
        }
        else if (inputViolation == true)
        {
            printf("You eneterd more than one letter\n");
        }
        else
        {
        inputLoopEnd = 1;
        }
}
while( inputLoopEnd == false );
Robo Maklen
  • 152
  • 1
  • 11
  • `inputViolation == true` looks horrible... I think it should be compared to at least some character. – MikeCAT Jul 18 '16 at 15:33
  • 1
    No, `gets()` cannot be used because it has unavoidable risk of buffer overrun, deprecated in C99 and deleted from C11. – MikeCAT Jul 18 '16 at 15:34
  • i was thinking that if the if it read anything other than 0 (true in c) on the input string the user entered more than one char. – Robo Maklen Jul 18 '16 at 15:35
  • Different solutions for different implemntations (linux, windows, space shuttle, ABS system, microwave oven, ...). We need to know what you are using and what level of **unportability** you are happy to accept. – pmg Jul 18 '16 at 15:35
  • @JMaklen, `0` is *false* in C. In fact, it is the only value that is false. – John Bollinger Jul 18 '16 at 15:38
  • @JMaklen, are you trying to prevent the user from inputting multiple characters, as your question seems to suggest, or to recognize when they input more than one, as your comment suggests? – John Bollinger Jul 18 '16 at 15:40
  • 0 won't be read and stored unless 0 is inputted. – MikeCAT Jul 18 '16 at 15:40
  • Not sure what you mean by portability. I am using this program in windows and it is a hangman game if thats any help. – Robo Maklen Jul 18 '16 at 15:40
  • @JohnBollinger Like I said if the user inputs more than one char "inputViolation" would read something else than a 0 (making it true). I am trying to prevent the user from imputing multiple chars. – Robo Maklen Jul 18 '16 at 15:43
  • 1
    The Windows documentation (MSDN) has an entry for [`ReadConsole()`](https://msdn.microsoft.com/en-us/library/windows/desktop/ms684958(v=vs.85).aspx). It has a C++ tag, I believe it can be used in C. – pmg Jul 18 '16 at 16:00
  • @pmg What do you mean by it has a C++ tag. Im sorry if I should know this but I am a new programmer. – Robo Maklen Jul 20 '16 at 00:54
  • @JMaklen: I do not usually code for Windows, with Windows API. The MSDN documentation does not specify C so maybe the function internals throw exceptions or something only available in C++. If that's the case, you cannot use `ReadConsole()` in C (but I believe this is more of a documentation glitch than a real impossibility). – pmg Jul 20 '16 at 09:22

3 Answers3

3

You could use the getc family of functions.

Have a look at http://quiz.geeksforgeeks.org/difference-getchar-getch-getc-getche/ for example.

Stefan Winkler
  • 3,871
  • 1
  • 18
  • 35
  • 1
    I wouldn't exactly call them "`getch` family of functions", because the question is about **C**, whereas naming the entire family of functions after one, which isn't even a member of the C standard I/O, but is part of Microsoft extension `` would be misguiding. "`getc` family of functions" would be more correct. – user3078414 Jul 18 '16 at 15:43
0

It seems you want to read input one line at a time (i.e. the user types a one-letter guess and then <enter>), and you want to verify that the guess indeed contains only a single letter. Couching the problem in those terms perhaps makes it clearer how fgets() could be applied, as that function's purpose is to read one line at a time. Having read a whole line -- or at least as much as the buffer can accommodate -- you can validate it and extract the guess.

scanf() is hard to use properly, so I do recommend the fgets() approach. If you insist on using scanf(), however, then you might do it like this:

// consumes leading whitespace, inputs one character, then consumes any
// immediately-following run of spaces and tabs:
int result = scanf(" %c%*[ \t]", &guessLetter);

if (result == EOF) {
    // handle end-of-file ...
} else {
    assert(result == 1);  // optional; requires assert.h

    int nextChar = getchar();

    if ((nextChar == '\n') || (nextChar == EOF)) {
        // handle multiple-character guess ...
    } else if (!isalpha(guessLetter)) {
        // handle non-alphabetic guess ...
    } else {
        // it's valid ...
    }
}
John Bollinger
  • 160,171
  • 8
  • 81
  • 157
  • Why do you have this code? (result == EOF) I am getting input from the input stream the user has entered not a file? – Robo Maklen Jul 20 '16 at 01:00
  • @JMaklen, end-of-file can occur on the standard input, too, in any of several ways. Even if you do not expect that result in the ordinary use of your program, it is poor form to assume that it will never happen. – John Bollinger Jul 20 '16 at 03:10
  • How could i get a EOF if im using scanf? The user can enter a value but how would he enter a file? – Robo Maklen Jul 30 '16 at 00:42
  • @JMaklen, C follows the Unix tradition: every data source and sink is called a "file". "End of *file*" is synonymous with end of *data*, and it can be observed on the standard input if that is redirected from a pipe or disk file. Under some circumstances it can also be signaled manually by the user by typing a particular character; e.g. control-D often has this meaning on Unix. – John Bollinger Jul 30 '16 at 03:19
-1

Do not use things like fgets() or fputs() etc... They are falling out of use.

As you can see from the description here... this function is designed to handle objects of type str, and you are more focused on using chars at the moment so why not just handle only chars to make life easier.

You can't do this the way you think you can...

scanf(" %c", &geussLetter);
scanf ("%c", &inputViolation);

This can't work because even if the user enters in only one char the way they are supposed to, it's still going to trigger your inputViolation scheme.

Edit: 12:14pm 7/20/2016

I really like the elegance of MOHAMAD's solution on the community wiki.

So I edited to fit your situation and it works well here too. Same idea...

#include <stdio.h>  
#include <stdlib.h> 

int clean_stdin()
{
    while (getchar() != '\n');
    return 1;
}

int main(void)
{
    int first_time_around = 0;
    char theguess = 0;
    char c;
    do
    {
        if (first_time_around == 0)
            first_time_around++;
        else
            printf("Wrong input \n");

        printf("Enter guess number: \n");

    } while (((scanf("%c%c", &theguess, &c) != 2 || c != '\n') 
             && clean_stdin()) || !isalpha(theguess));

    return 0;
}
Community
  • 1
  • 1
Jeremy Gamet
  • 165
  • 7