-1

I wanna reproduce the terminal behavior when the input is just a new line (keeps printing the same string), but don't know how to do it.

Example: When the user just inputs a new line, the terminal keeps printing the directory, until a real command is inserted

int main()
{
    char userInput[1024];
    while (1)
    {
        printf("directory »» ");
        scanf("%[^\n]" , userInput); // This scanf doesn't work
        while (userInput[0] == '\n')  // If the input is only a new line char, keep asking for more inputs and printing the directory
        {
            printf("directory »» ");
            scanf(" %[^\n ]" , userInput); // This scanf doesn't work
        }

        //Input isn't a NewLine, process the input
        process_Input_Function(userInput); //Isn't empty, search for my created commands
    }
}

At the first enter press, it enters the loop, reproduce 1 time, and then the scanf doesn't detect new lines anymore, it just skips and waits to a real string. What can i type inside of the scanfto detect a new line input and keep printing that string till a real command is inserted?

I tried with scanf("%c"...) but the problem with a char, is that i can't process the whole string command, if isn't empty

marcospb19
  • 45
  • 10

2 Answers2

1

First of all, your two scanf calls are different. The first one is

scanf("%[^\n]", userInput);

which looks for anything that's not a newline, as you wish to do.

But the second one is

scanf(" %[^\n ]", userInput);

which is also looking for a space before the input, followed by any character that is also not a newline or a space. Thus, scanf is waiting for the space.


IMHO, the best way to recreate this behavior is going to be in the parsing step, after you have gotten the command from the command line. Essentially, your command input loop would look like this:

char *userInput = NULL;
size_t n = 0;
while (true) {
    // print the prompt
    printf(">");
    // get the line
    ssize_t userInputLength = getline(&userInput, &n, &stdin); 
    // parse the input, using a function you wrote elsewhere
    parse(userInputLength, userInput);
}

(Note the use of POSIX getline() instead of scanf. This is a more recent standard library function that does exactly the task of getting a line of user input, and also allocates the buffer using malloc and realloc so that you don't have to care about buffer overflows or even sizing the buffer at all.)

The user input function wouldn't care that the userInput portion was blank. The function that would care is the parse function, which will simply interpret a blank userInput string as "do nothing" and continue on its merry way.

Jonathan Leffler
  • 730,956
  • 141
  • 904
  • 1,278
TheHans255
  • 2,059
  • 1
  • 19
  • 36
  • Just try making it exactly like the first one. Does that work? – TheHans255 Nov 15 '18 at 16:34
  • @marcospb19 OK, makes sense. I just added to my answer to suggest how you would actually pull this behavior off. – TheHans255 Nov 15 '18 at 16:44
  • I understood, but seems like this also created an infinite loop (the space behind usually stops that, but i don't figured a way to fix your code). – marcospb19 Nov 15 '18 at 16:50
  • 1
    The 2nd `"\n"` in `scanf("%[^\n]\n", userInput);` causes `scanf()` to consume all whitespace include the `'\n'` and all other following WS until non-white-space if entered. – chux - Reinstate Monica Nov 15 '18 at 17:38
  • Note that [trailing white space in a `scanf()` format string is a UI/UX disaster](https://stackoverflow.com/questions/19499060/what-is-the-effect-of-trailing-white-space-in-a-scanf-format-string). – Jonathan Leffler Nov 15 '18 at 18:38
  • @JonathanLeffler Oh, I was not aware of this. Thank you! Since this is getting a line from user input, I'll change my suggestion. – TheHans255 Nov 15 '18 at 18:40
  • At a pinch, you could use `scanf("%[^\n]%*[\n]", userInput);` which suppresses the assignment and looks for precisely a newline (but you'll never know whether the newline was matched or not). On the whole, there are better ways, as documented in the link. – Jonathan Leffler Nov 15 '18 at 18:42
0

Hmm, the code I gave pretty much does that with one exception, it doesn't display a prompt each time...

Is this what you mean:

#include <stdio.h>
#include <stdlib.h>
#include <string.h> // For the memset()

int main() {

    char userInput[1024];

    while (1) {
        printf("»»» ");

        fgets(userInput, 1024, stdin);

        while (userInput[0] == '\n')
        {
            printf(">>> ");
            memset(userInput, '\0', 1024);
            fgets(userInput, 1024, stdin);
        }

        // Your command can be accessed from here //
        printf("Command entered: %s\n", userInput);

        printf("Input isn't a NewLine\n");
    }

}

I changed the scanf() to fgets() to read from stdin so that we don't overwrite the buffer.

Jonathan Leffler
  • 730,956
  • 141
  • 904
  • 1,278
Nunchy
  • 948
  • 5
  • 11