按Enter键退出循环(C编程)
我的程序有点问题我正在尝试编码..基本上我想在我的循环中逐个输入符号,当我完成时我只想按回车键以退出循环然后打印将字符串输出到控制台。 然而,这似乎不起作用,我已经尝试了几个小时没有掌握它。 这是我的代码
#include int main(int argc, char *argv[]){ int i = 0; char text[i]; char symbol; while(1){ scanf("%s", &symbol); if(symbol == 13){ //13 should be the ascii value for enter break; } text[i] = symbol; i++; } printf("%s", text); getch(); return 0; }
-
%s
读一个字。 如果要使用scanf
读取字符,请使用%c
。 - C字符串终止NUL,首先必须在打印之前终止字符串。
-
char text[i]
– 此时i
为零。 您将无法在此处存储您的字符串。 要么在编译时知道最大大小(并在附加时检查运行时),要么根据需要动态分配内存。
注意:从流中进行裸扫描只是要求很多麻烦。 喜欢读行。
您可以使用termcaps将终端设置为原始模式:
term.c_lflag &= ~(ICANON); term.c_lflag &= ~(ECHO); term.c_cc[VMIN] = 1; term.c_cc[VTIME] = 0; if (tcsetattr(0, TCSADRAIN, &term) == -1) return (-1);
然后使用function:
int main(int ac, char **av, char **env) { char *name_term; struct termios term; if ((name_term = getenv("TERM")) == NULL) return (-1); if (tgetent(NULL, &name_term) == ERR) return (-1); if (tcgetattr(0, term) == -1) return (-1); grab_key(); return (0); } int grab_key() { char buffer[3]; while (1) { read(0, buffer, 3); if (buffer[0] == 13) printf("Exit !"); } return (0); }
并将您的终端设置为“正常”模式:
struct termios term; if (tcgetattr(0, &term) == -1) return (-1); term.c_lflag = (ICANON | ECHO); if (tcsetattr(0, 0, &term) == -1) return (-1);
三个问题。 首先是你如何阅读角色:
scanf("%s", &symbol);
%s
格式说明符用于读取字符串。 你没有传入一个字符串,而是一个字符的地址。 这将导致scanf
从symbol
地址开始以多个字符读取,并继续进入可能跟随的任何字节。 这是未定义的行为。
要读取单个字符,请改用%c
格式说明符:
scanf("%c", &symbol);
第二期:
if(symbol == 13){
所有系统上的换行符不一定是ASCII 13。 改为使用换行代码转义代码:
if(symbol == '\n'){
第三期:
int i = 0; char text[i];
这将创建一个0大小的数组。 为了简单起见,给这个数组一些已知的固定大小:
char text[100];
然后你的循环需要检查你输入的字符是否太多。
首先,数组不会神奇地增加它的大小只是因为你增加了用来设置它的大小的变量(代码中的text[i]
中的text[i]
),你应该动态分配内存( malloc
, realloc
或calloc
),并记住释放它。 你的代码应该是这样的:
int main(int argc, char *argv[]){ int i = 0; char* text = malloc(sizeof(char)); char symbol; char* aux; while(1){ symbol = getchar(); //Use getchar to read only one char, scanf would be more problematic if(symbol == 13){ //13 should be the ascii value for enter break; } text[i] = symbol; if ((aux = (char*)realloc(text, sizeof(char)*(i+1))) == NULL){ // Handle error return -1; } text = aux; i++; } text[i] = '\0'; //Remember to set last char in your string to '\0' or printf won't work properly printf("%s", text); free(text); getch(); return 0; }
您可以使用fgetc(3)但它可能不会工作(因为stdin在C标准库中缓存 – 请参见setvbuf(3) ,在ttys的内核中,请阅读有关ttys的更多信息)。 因此,只有当用户按下返回键时,整行才会发送到您的程序。
在实践中,它是特定的操作系统; 我希望你在Linux或其他POSIX系统上。 我强烈建议使用ncurses或readline ; 另见termios(3)
在Windows上,当您按Enter键时 ,它将被读为\r\n
,而不仅仅是\r
\r\n
。 所以你可能想试试这个:
while(1){ scanf("%c", &symbol); //use %c to read a character if(symbol == '\r'){ scanf("%c", &symbol); if(symbol == '\n') break; } text[i] = symbol; i++; }
此外,您正在创建一个无数的数组,然后尝试将数据放入其中。 这不行。 你最好先分配一些内存然后再读入它:
char text[1024]; int i =0; // then increase i up to 1023
更重要的是,如果您的唯一目的是捕获Enter
命中,您根本不需要text
,只需symbol
就可以满足您的需求。