我正在为我的学校分配作业时间表,以下代码是模块的一部分,用于输入新作业的数据,然后将该数据写入文件。由于作业说明可能是一个冗长的段落,因此我决定允许用户在按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键时读取字符串,以便继续执行。
答案 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);
}