C - 有没有办法用 'Enter' 以外的键终止字符串输入?
C - Is there a way to terminate string input with a key other than 'Enter'?
我正在为我的学校开发一个作业调度程序,下面的代码是一个模块的一部分,用于为新作业输入数据,然后将该数据写入文件。由于作业描述可能是一个冗长的段落,我决定允许用户在按下 Enter 键时移动到一个新行以便于输入。到目前为止,我的代码可以按预期工作。
描述是单个字符串,但通常以回车键结束。是否可以用另一个键终止字符串?例如逃生键?如果是这样,我该怎么做?
我正在考虑使用转义 '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);
//...
}
我希望在按下转义键时读取字符串,以便继续执行。
默认情况下输入是行缓冲的。您可以使用 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
阅读更多关于:
在评论中,我向提问者建议,通过使用双换行符(空行)而不是 ESC 来指示输入结束,可以更好地解决他的问题。
他要求实现,这里是一个实现。 fgets_until_blankline
函数会读取多行,按两次回车返回。
#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);
}
我正在为我的学校开发一个作业调度程序,下面的代码是一个模块的一部分,用于为新作业输入数据,然后将该数据写入文件。由于作业描述可能是一个冗长的段落,我决定允许用户在按下 Enter 键时移动到一个新行以便于输入。到目前为止,我的代码可以按预期工作。 描述是单个字符串,但通常以回车键结束。是否可以用另一个键终止字符串?例如逃生键?如果是这样,我该怎么做?
我正在考虑使用转义 '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);
//...
}
我希望在按下转义键时读取字符串,以便继续执行。
默认情况下输入是行缓冲的。您可以使用 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
阅读更多关于:
在评论中,我向提问者建议,通过使用双换行符(空行)而不是 ESC 来指示输入结束,可以更好地解决他的问题。
他要求实现,这里是一个实现。 fgets_until_blankline
函数会读取多行,按两次回车返回。
#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);
}