【问题标题】:Is it possible to detect just the new line input with scanf?是否可以使用 scanf 仅检测新行输入?
【发布时间】:2018-11-15 18:49:29
【问题描述】:

我想重现终端行为,如果可能的话使用scanf

当用户刚刚输入一个新行时,终端会一直打印目录,直到插入一个真正的命令。 插入新行时函数scanf 的正常行为是不断跳空行,等待用户真正插入有效字符。

观察:当我执行 ./main.out 时,此终端模拟正在运行,这意味着我不是在谈论我的操作系统终端,而是在谈论我的程序中的 C 模拟终端。

当您插入空行时,scanf 通常会发生什么:

realPC:~/realDirectory$ ./main.out //starting our simulated terminal
pc:~/Desktop$ '\n'
'\n'
'\n'
"COMMAND\n"         //PROCESS THE COMMAND!
pc:~/Desktop$       //waiting...

我想要什么:

realPC:~/realDirectory$ ./main.out //starting our simulated terminal
pc:~/Desktop$ '\n'
pc:~/Desktop$ '\n'
pc:~/Desktop$ '\n'
pc:~/Desktop$ "COMMAND\n" //Process the command here
pc:~/Desktop$             //waiting...

这个目录只是一个例子,我想打印任何消息(例如,在空输入后继续打印箭头">>>"),问题是scanf似乎甚至不考虑'\n'一个输入,所以我不能打印任何东西

我知道fgets(userInput, 1024, stdin) 可以代替scanf,但我想知道是否可以使用scanf 函数(我不习惯fgets,如果可能的话,我也接受其他解决方案建议)

这是代码(scanf 并没有像我假装的那样同时用于两种用途):

int main()
{
    char userInput[1024];
    char pwd[] = "pc:~/marcospb19"; // Directory that keeps being printed

    while (1)
    {
        printf("%s$ " , pwd); // Print the directory just like terminals do

        scanf(" %s" , userInput); // I wanted this to enter the while and keep printing directory
        while (userInput[0] == '\n') // Keeps the input inside the loop, if is a new line
        {
            puts("We're inside this loop! that's good, now keep printing directory...");
            printf("%s$ " , pwd); // Directory printed, next: take input again
            scanf(" %s" , userInput); // This should be able to receive '\n'.
            // This loop should continue if user types '\n'
        }

        // Now, you can process the input, it isn't empty!
        printf("Process the input: %s\n", userInput);
    }
}

显然,当我说用户键入'\n' 时,他只是在按回车键(不是真正键入它)。

【问题讨论】:

  • 我怀疑fgets 和一些输入按摩会比scanf 为您提供更好的服务(无论如何通常都是这样)。
  • 您可能会发现fgets + sscanf 比单独使用scanf 更容易。

标签: c


【解决方案1】:

是否可以使用 scanf 仅检测新行输入?

是的

  char eol[2];
  if (scanf("%1[^n]", eol) == 1) {
    puts("Input with just new line");
  else {
    // read the line via other means
  }

scanf() 和尝试读取用户输入的 的问题包括:

  • 在宽度限制中编码困难。
  • 需要在行的前一部分之后消耗"\n"
  • 很难在 "\n" 唯一输入。

我不习惯fgets

最好学习使用标准库中最好的工具来阅读,而不是编写一些替代代码。

【讨论】:

    【解决方案2】:

    scanf rapidly gets complicated 因为它混淆了读取输入和处理输入。当您只想阅读一行并对其进行处理时,fgets 更合适。阅读该行,然后随心所欲地处理它。您甚至可以使用sscanf 留在scanf 家族中。

    #include <stdio.h>
    #include <string.h>
    
    int main()
    {
        char userInput[1024];
        char pwd[] = "pc:~/marcospb19"; // Directory that keeps being printed
    
        printf("%s$ " , pwd);
        while (fgets(userInput, sizeof(userInput), stdin) != NULL)
        {
            if( strcmp(userInput, "\n") == 0 ) {
                puts("Empty input.");
            } 
            else {
                puts("Some input");
            }
    
            printf("%s$ " , pwd);
        }
    
        puts("");
    }
    

    这还可以让您进行更复杂的处理,例如查找空行。

        if( strspn(userInput, " \t\r\n") == strlen(userInput) ) {
            puts("Blank input.");
        }
    

    请注意,fgets 会将换行符留在末尾,因此您可能必须在处理之前将换行符从userInput 中删除。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2015-06-09
      相关资源
      最近更新 更多