首页 > 解决方案 > 如何使用 scanf 和打印目录(如终端)仅检测新行输入

问题描述

当输入只是一个新行(继续打印相同的字符串)时,我想重现终端行为,但不知道该怎么做。

示例:当用户刚刚输入一个新行时,终端一直打印目录,直到插入一个真正的命令

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
    }
}

在第一次enter按下时,它进入循环,再现 1 次,然后scanf不再检测新行,它只是跳过并等待一个真正的字符串。我可以在里面输入什么scanf来检测新的行输入并继续打印该字符串直到插入真正的命令?

我试过了,scanf("%c"...)但是一个字符的问题是我不能处理整个字符串命令,如果不是空的

标签: c

解决方案


首先,你的两个scanf电话是不同的。第一个是

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

它会按照您的意愿查找任何不是换行符的内容。

但是第二个是

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

它也在输入之前寻找一个空格,后跟任何不是换行符或空格的字符。因此, scanf 正在等待空间。


恕我直言,在您从命令行获取命令之后,重新创建此行为的最佳方法是在解析步骤中。本质上,您的命令输入循环如下所示:

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);
}

(注意使用 POSIXgetline()而不是scanf. 这是一个更新的标准库函数,它完全执行获取一行用户输入的任务,并且还使用分配缓冲区mallocrealloc因此您不必关心缓冲区溢出或甚至完全调整缓冲区的大小。)

用户输入功能不会关心该userInput部分是否为空白。需要关心的函数是parse函数,它将简单地将空白userInput字符串解释为“什么都不做”并继续其愉快的方式。


推荐阅读