所以,我看过几个问同样问题的帖子,但没有一个帖子适合我。好吧,他们中途工作,就像他们工作时我不做我在这里做的事情。我要做的是让它显示几行文字,要求输入继续,并显示更多的文字,这样它不会只给你一个巨大的文字墙来同时阅读所有文字。
这是我所拥有的一切,我会记下我在尝试等待进入的地方。如果它有所作为,我就在窗户上。
#include<stdio.h>
#include<stdlib.h>
#include<string.h>
#include<process.h>
#include<conio.h>
#include<ctype.h>
//void playerName (char* playername){
//FILE* playerNameFile = fopen("player.data","w");
//fprintf(playerNameFile, "%s", playerName);
//}
int main(){
char response;
char playername[20];
char enter = 0; //For Enter
system("cls");
printf("Would you like to embark on an adventure?\n Y/N?:\n\n\n\n");
response = toupper(getch());
if (response=='Y'){
printf("Before we start, what's your name?\n Your name is: ");
scanf("%s",playername);
printf("%s, Story Text.\n");
printf("Story Text\n");
printf("Story Text.\n");
printf("Story Text\n");
printf("Story Text\n");
printf("Press enter to continue\n");
while (enter != '\r' && enter != '\n') { enter = getchar(); } //For Enter
printf("Story Text\n");
printf("Story Text\n");
printf("Story Text");
printf("Story Text \n");
printf("Story Text\n");
printf("Story Text\n");
printf("Story Text\n");
printf("Press enter to continue\n");
while (enter != '\r' && enter != '\n') { enter = getchar(); } //For Enter
printf("Story Text\n");
printf("Story Text\n\n");
printf("Story Text\n");
printf("Story Text\n");
}
else if (response=='N'){
printf("Well, I'll see you later then!");
exit(0);
}
printf("Embark on your quest?\n Y/N?");
response = toupper(getch());
if (response=='Y'){
system("cls");
printf("'\nStory Text\n");
printf("'Story Text\n");
printf("The end for now");
}
else if (response=='N'){
printf("Come back when you are ready to embark on your quest.");
exit(0);
}
return 0;
}
我假设while
部分是它的问题,但我想不出一种方法可以让它在我所得到的条件下工作。有没有办法可以做到这一点?
答案 0 :(得分:2)
当getchar()
从键盘读取用户输入的字符时,输入流中可能还有额外的字符。在尝试再次阅读之前,您需要丢弃这些额外的字符。
我最初没有注意到对scanf()
的调用(您的程序会从某些空格中受益以提高可读性),但scanf()
也会在输入流中留下字符。由于这个原因,将scanf()
和getchar()
结合起来总是很棘手,最好的解决方案可能是对所有用户输入使用fgets()
。
但是,为了避免过多地更改输入代码,您可以坚持使用scanf()
和getchar()
。由于您需要在scanf()
和getchar()
之后清除输入流,因此最好编写一个函数clear_stream()
:
void clear_stream(void)
{
int c;
while ((c = getchar()) != '\n' && c != EOF) {
continue;
}
}
这可以合并到函数get_single_char()
中,也可以在调用scanf()
后单独使用,以清除输入流。当您调用clear_stream()
时,输入流中必须至少有一个字符,否则该函数将等待更多输入。在C标准(C11§7.21.5.22)中明确不允许使用fflush(stdin)
来清除输入流。 Windows系统为此定义了行为,但它不可移植(例如,在Linux上不起作用)。 You can read more about this issue here
这是一个玩具示例。请注意在调用scanf()
时使用宽度规范以避免缓冲区溢出。
#include <stdio.h>
int get_single_char(void);
void clear_stream(void);
int main(void)
{
int choice;
char name[100];
printf("Enter name: ");
scanf("%99s", name);
clear_stream();
printf("Play a game, %s (y/n)? ", name);
choice = get_single_char();
if (choice == 'y') {
printf("Press ENTER to continue:");
get_single_char();
} else {
puts("That was uninspiring!");
}
puts("bye");
return 0;
}
int get_single_char(void)
{
int input;
input = getchar();
if (input != '\n') {
clear_stream();
}
return input;
}
void clear_stream(void)
{
int c;
while ((c = getchar()) != '\n' && c != EOF) {
continue; // discard extra characters
}
}
答案 1 :(得分:1)
此示例使用popen()
写入作为子进程运行的较少命令,可能会为您节省很多麻烦,并根据具体情况为用户提供更好的体验,因为少用它们可以来回滚动。
取决于您的计划需要什么级别的控制。
我测试了这段代码。它有效。
更新:我添加了pclose()
因此它将关闭fd,因此知道输入流完成的次数较少,而pclose()将等待子进程运行较少的终端(当用户按q)。
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <sys/stat.h>
int main(void)
{
FILE *lessfp;
if ((lessfp = popen("less -P\"[SPACE] next page, [u] prev page, [q] done:\"", "w")) == NULL) {
perror("popen");
exit(-1);
}
printf("writing data\n");
for (int i = 0; i < 1000; i++) {
fprintf(lessfp, "This is some stuff %d\n", i++);
}
pclose(lessfp);
printf("less exited!\n");
}
答案 2 :(得分:1)
此行 scanf(“%s”,播放器名称); 用户通常按Enter键以标记输入结束,但scanf仅读取新行符号(回车)。
接下来,在while (enter != '\r' && enter != '\n') { enter = getchar(); } //For Enter
行,getchar从前一个输入中吸取了新行-char。
由于你没有在新输入之前更改enter变量,你仍然坚持阅读new-line-char。
结果,输入名称使您的代码不间断地运行。
尝试在任何输入操作后添加 fflush(stdin); 指令。并记得重置输入变量。
答案 3 :(得分:0)
暂停使用getc()
。在第一个scanf()
之后并在每次调用getc()
之后暂停多余的字符以暂停。正如David Bowling所述,不要fflush(stdin)
因为它会导致未定义的行为。
请参阅this相关帖子。
...
scanf("%s",playername);
/* discard extra chars */
while((c= getchar()) != '\n' && c != EOF);
printf("Story Text\n");
printf("Story Text.\n");
printf("Story Text\n");
printf("Story Text\n");
/* pause */
printf("Press enter to continue\n");
getc(stdin);
while((c= getchar()) != '\n' && c != EOF);
printf("Story Text\n");
printf("Story Text\n");
printf("Story Text");
printf("Story Text \n");
printf("Story Text\n");
printf("Story Text\n");
...
答案 4 :(得分:0)
连续使用 scanf() 会导致缓冲区输入问题。对于窗口用户,应该使用 fflush(stdin) 但对于 Linux,它不起作用。因此 Linux 用户必须在第二个 scanf() 而不是 fflush(stdin) 之前重复第一个 scanf()。这是我的程序代码:
/* Driver program to test above functions*/
int main()
{
/* Start with the empty list */
struct Node* head = NULL;
char decision = 'y';
int count=1, val;
while(decision=='y'){
printf("Input the data for node %d ",count);
scanf("%d", &val); <--------------------------------------first scanf()
insertAtFirstLocation(&head, val);
printf("\nEnter more <y>es/<n>o ? ");
//used instead of fflush(stdin) to refresh input buffer
scanf("%d", &val); <--------------------------------------repeated to refresh
scanf("%c", &decision); <---------------------------------second scanf() for new input
count++;
}
printList(head);
return 0;
}