简体   繁体   English

如何在不按C键的情况下放置换行命令?

[英]How do i put a newline command without pressing enter in C?

I'm on Linux, using C99 and my problem is: I programmed a multi-option based on integers. 我在Linux上,使用C99,但我的问题是:我基于整数编程了一个多选项。 For every iteration past the first, inputting more integers than needed for the array would trigger other menu options as they remain into the buffer. 对于第一次迭代之后的每次迭代,输入比数组所需更多的整数将触发其他菜单选项,因为它们仍保留在缓冲区中。 I wanted to avoid the fflush(stdin) function as I read it causes undefined behaviour, so i tried with while ((select = getchar()) != '\\n') , but in the first iteration, I need to press Enter for the menu to appear in the first place. 我想避免fflush(stdin)函数,因为它会导致未定义的行为,因此我尝试了while ((select = getchar()) != '\\n') ,但是在第一次迭代中,我需要按Enter使菜单显示在第一位。 Can I send a Newline to the buffer to avoid the problem? 我可以发送换行符到缓冲区来避免此问题吗? Also, I declared select as an int 另外,我声明selectint

Here is the part of the code that causes the problem: 这是导致问题的代码部分:

for(;;) {
    while ((select = getchar()) != '\n') { }
    printf("\n\nWhat operation?\n1. Define array\n2. Delete element\n3. Add element\n4. Order array\n5. Randomize array\n6. Print array\n0. Exit\n");
    scanf("%d", &select);
    switch(select) {...}

Use fgets to read a line. 使用fgets读取一行。 Parse the line with sscanf. 用sscanf解析该行。 Parsing for an integer and a trailing non-whitespace character will allow detection of any input that follows the integer. 解析整数和结尾的非空白字符将允许检测到该整数之后的任何输入。
EDIT to improve due to @chux's comment 由于@chux的评论,编辑进行了改进

#include <stdio.h>

int main ( void) {
    char buffer[100] = "";
    char extra = '\0';
    int scanned = 0;
    int choice = 0;

    do {
        printf("\n\nWhat operation?\n1. Define array\n2. Delete element\n3. Add element\n4. Order array\n5. Randomize array\n6. Print array\n0. Exit\n");
        if ( fgets ( buffer, sizeof buffer, stdin)) {
            if ( 1 == ( scanned = sscanf ( buffer, "%d %c", &choice, &extra))) {// the space will consume whitespace and %c a non-whitespace character
                printf ( "choice %d\n", choice);
                if ( 0 > choice || choice > 6) {
                    scanned = 0;
                }
            }
            if ( 1 != scanned) {
                printf ( "\t\tenter a number 0 to 6\n");
            }
        }
        else {
            fprintf ( stderr, "problem fgets\n");
            return 0;
        }
    } while ( 1 != scanned);

    return 0;
}

In pure standard C, what you want is probably impossible (and certainly ill-defined) and unclear. 在纯标准C中,您想要的可能是不可能的(当然是不确定的)并且不清楚。 The C11 standard n1570 does not know about terminals or keyboard (so about the enter key), but only about standard streams . C11标准n1570不了解终端或键盘(因此不知道Enter键),而仅了解标准流 See also this answer to a question close to yours. 另请参阅答案,以解决您附近的问题。

In practice, if you are on some POSIX system (which I guess you are on), the terminal has a line discipline managed by the kernel. 实际上,如果您使用的是POSIX系统(我猜您在使用),则终端具有由内核管理的线路规则 However, the standard input might not be a terminal (with redirections or pipelines ) and you could check if it is one by using isatty(3) as isatty(STDIN_FILENO) ... 但是,标准输入可能不是终端(具有重定向管道 ),并且您可以通过将isatty(3)用作isatty(STDIN_FILENO)来检查它是否为一个。

I recommend using some library like readline or ncurses when that is the case. 在这种情况下,我建议使用诸如readlinencurses之类的库。

BTW, your use of select name is confusing (since select(2) was an old system call, today superseded by poll(2) ). 顺便说一句,您对select名称的使用令人困惑(因为select(2)是旧系统调用,今天已由poll(2)取代)。

If you are restricted to pure C standard functions, read carefully the documentation of scanf , and use its return count. 如果仅限于纯C标准函数,请仔细阅读scanf的文档,并使用其返回计数。 You certainly cannot (portably) put a newline (or any other characater) into some input stream like stdin . 您当然不能(方便地)将换行符(或任何其他字符)放入某些输入流(例如stdin But read carefully about ungetc . 但是请仔细阅读有关ungetc的内容

I recommend to compile with all warnings and debug info (so gcc -Wall -Wextra -g with GCC ) and to learn to use the gdb debugger to understand the behavior of your program. 我建议编译所有警告和调试信息(所以gcc -Wall -Wextra -g 和GCC一起使用 ),并学习使用gdb调试器来了解程序的行为。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM