Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

What is the simplest way of getting user input in C?

Tags:

There seem to be a LOT of ways you can get user input in C.

What is the easiest way that requires little code?

Basically I need to display this:

Enter a file name: apple.text

Basically I need to ask the user for a file name. So I need something that just gets that one word that the user will be inputting.

like image 434
antonpug Avatar asked Oct 20 '11 06:10

antonpug


People also ask

How we can take input from user in C?

In C programming, scanf() is one of the commonly used function to take input from the user. The scanf() function reads formatted input from the standard input such as keyboards.

Which function is used for taking input in C program?

For taking input in C, we use the built-in function of the C scanf(). scanf() method reads the input from standard input stream stdin and scans that input as per the type specified. scanf(“%A”, &variableOfAType); The above syntax is for taking input from the user.

What is stdin and stdout in C?

In computer programming, standard streams are interconnected input and output communication channels between a computer program and its environment when it begins execution. The three input/output (I/O) connections are called standard input (stdin), standard output (stdout) and standard error (stderr).


1 Answers

The simplest "correct" way is probably this one, taken from Bjarne Stroustrup's paper Learning Standard C++ As A New Language.

(Note: I changed Bjarne's code to check for isspace() instead of just end of line. Also, due to @matejkramny's comment, to use while(1) instead of while(true)...and so long as we're being heretical enough to edit Stroustrup's code, I've subbed in C89 comments instead of C++ style too. :-P)

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

void quit() /* write error message and quit */
{
    fprintf(stderr, "memory exhausted\n");
    exit(1);
}

int main()
{
    int max = 20;
    char* name = (char*) malloc(max); /* allocate buffer */
    if (name == 0) quit();

    printf("Enter a file name: ");

    while (1) { /* skip leading whitespace */
        int c = getchar();
        if (c == EOF) break; /* end of file */
        if (!isspace(c)) {
             ungetc(c, stdin);
             break;
        }
    }

    int i = 0;
    while (1) {
        int c = getchar();
        if (isspace(c) || c == EOF) { /* at end, add terminating zero */
            name[i] = 0;
            break;
        }
        name[i] = c;
        if (i == max - 1) { /* buffer full */
            max += max;
            name = (char*) realloc(name, max); /* get a new and larger buffer */
            if (name == 0) quit();
        }
        i++;
    }

    printf("The filename is %s\n", name);
    free(filename); /* release memory */
    return 0;
}

That covers:

  • skipping whitespace until you reach character input
  • expanding the string buffer dynamically to fit arbitrary size strings
  • handling conditions of when memory can't be allocated

Are there simpler but broken solutions, which might even run a bit faster? Absolutely!!

If you use scanf into a buffer with no limit on the read size, then your input exceeds the size of the buffer, it will create a security hole and/or crash.

Limiting the size of the reading to, say, only 100 unique characters of a filename might seem better than crashing. But it can be worse; for instance if the user meant (...)/dir/foo/bar.txt but you end up misinterpreting their input and overwriting a file called bar.t which perhaps they cared about.

It's best to get into good habits early in dealing with these issues. My opinion is that if your requirements justify something close-to-the-metal and "C-like", it's well worth it to consider the jump to C++. It was designed to manage precisely these concerns--with techniques that are robust and extensible, yet still perform well.

like image 74
HostileFork says dont trust SE Avatar answered Nov 05 '22 06:11

HostileFork says dont trust SE