C-除了“ Enter”键以外,是否有其他方法可以终止字符串输入?

时间:2019-04-06 04:53:56

标签: c string fgets keycode

我正在为我的学校分配作业时间表,以下代码是模块的一部分,用于输入新作业的数据,然后将该数据写入文件。由于作业说明可能是一个冗长的段落,因此我决定允许用户在按Enter键时移到新行,以便于输入。到目前为止,我所拥有的代码可以按需工作。 描述是单个字符串,但是通常以回车键结束。是否可以用另一个键终止字符串?例如,Escape键?如果是这样,我该怎么做?

我当时正在考虑使用转义'Esc'键终止字符串输入,但是我不确定用哪个代码或转义序列表示该键。

typedef struct {
    char title[60];
    Time duration;
    Date deadline;
    char descrptn[10000];
} Project;

void setStudioProject() {
    Project newProj;
    FILE *fpProj;

    system("cls");
    printf("-----PROJECT SETUP-----\n\n\n");
    //Prompt for project information
    printf("Title: ");
    fgets(newProj.title, 60, stdin);
    fflush(stdin);
    printf("\n\nDescription: \n");
    printf("(No more than 1000 words)\n");

    //loop of concern
    while (fgets(newProj.descrptn, 10000, stdin)) {
        if (getchar() == '\r') { //Whenever the user presses the enter key
            printf("\n"); //...move to a new line
        }
    }
    fflush(stdin);
    //...
}

我希望在按Escape键时读取字符串,以便继续执行。

2 个答案:

答案 0 :(得分:3)

默认情况下,输入是行缓冲的。您可以使用ncurses(不这样做)或手动禁用:

#include <stdio.h>
#include <unistd.h>
#include <termios.h>
...
//ensure stdin is a terminal before modifying
if (isatty(STDIN_FILENO)) {
    struct termios t;
    tcgetattr(STDOUT_FILENO, &t);//get current params

    int linebufd = ((t.c_lflag & ICANON) > 0);//check if line-buffered
    if (linebufd) {
        t.c_lflag ^= ICANON;//disable canonical line-buffering
        tcsetattr(STDOUT_FILENO, TCSANOW, &t);//update attributes and enable immediate feedback
    }
}
setvbuf(stdin, NULL, _IONBF, 1);//make stdin stream unbuffered

详细了解:

答案 1 :(得分:1)

在评论中,我向提问者建议,使用双换行符(空白行)表示输入结束而不是ESC,可以更好地解决他的问题。

他要求实施,所以这里是该实施。 fgets_until_blankline函数将读取多行,按两次Enter键返回。

#include <stdio.h>
#include <string.h>

char *fgets_until_blankline(char *var, int varsize, FILE *file) {

    int inlen = 0;
    char *rc;

    var[0] = 0;
    while(rc = fgets(var+inlen, varsize-inlen, file)) {
        if(var[inlen] == '\n') {
            var[inlen] = 0;
            break;
        }
        inlen = strlen(var);
    }
    return rc;
}

int main() {

    char var[10000];

    fgets_until_blankline(var, sizeof(var), stdin);
    printf("%s", var);

}