如何在不转到下一行的情况下在 C 中使用 printf() 和 scanf()?
How to use printf() and scanf() in C without going to the next line?
我想在一行中获取出生日期:
#include <stdio.h>
int main()
{
int BirthYear,BirthMonth,BirthDay;
printf("Please enter your birth date: ");
scanf("%d",&BirthYear);
printf("/");
scanf("%d",&BirthMonth);
printf("/");
scanf("%d",&BirthDay);
return 0;
}
这是我的输出:
Please enter your birth date: YYYY
/MM
/DD
但我想得到这样的东西:
Please enter your birth date: YYYY/MM/DD
在输出中,它在每个 scanf() 之后转到下一行而不使用 \n。
我使用 VS Code 进行 IDM。
#include <stdio.h>
int main()
{
int BirthYear,BirthMonth,BirthDay;
printf("Please enter your birth date: ");
scanf("%d/%d/%d",&BirthYear,&BirthMonth,&BirthDay);
return 0;
}
您可以从 scanf
中获取多个值,然后用您喜欢的任何文本分隔(在本例中为 /
s)。
您可以通过在 scanf
函数的格式说明符中添加 '/'
字符来明确指定应该用 '/'
字符分隔三个输入数字。
然后,您可以通过检查 scanf
返回的值(这将是成功扫描和分配的项目数)来确保用户输入有效;如果该值不是 3
,那么您将(可能)需要清除输入缓冲区中的任何 'leftover' 个字符,使用 getchar()
循环直到换行符(或 end-of-file ) 被发现:
#include <stdio.h>
int main()
{
int BirthYear, BirthMonth, BirthDay;
int nIns = 0, ch;
while (nIns != 3) {
printf("Enter D.O.B. (as YYYY/MM/DD): ");
nIns = scanf("%d/%d/%d", &BirthYear, &BirthMonth, &BirthDay);
while ((ch = getchar() != '\n') && (ch != EOF))
; // Clear remaining in-buffer on error
}
printf("Entered data were: %d %d %d!\n", BirthYear, BirthMonth, BirthDay);
return 0;
}
这是一个使用 ansi 控制字符的解决方法。我不会这样做,只是为了证明这是可能的:
#define PREVLINE "3[F"
#define MSG "Please enter your birth date: "
int main(void) {
int BirthYear,BirthMonth,BirthDay;
printf(MSG);
scanf("%d",&BirthYear);
printf(PREVLINE MSG "%d/", BirthYear);
scanf("%d",&BirthMonth);
printf(PREVLINE MSG "%d/%d/", BirthYear, BirthMonth);
scanf("%d",&BirthDay);
printf("You entered: %d/%d/%d\n", BirthYear, BirthMonth, BirthDay);
}
请注意,这不是便携式的。终端需要支持这个才能工作。据我所知,没有 100% 可移植的方法来实现这一点。
如果你真的想做这些东西,我建议你看看the ncurses library
注:
始终检查 scanf
的 return 值以检测错误。
注2:
在每个 printf
语句后添加 fflush(stdout);
可能是个好主意。
其实我今天又写了一篇关于ascii控制字符的回答。这可能很有趣:
您可以像
那样使用 fflush(3) (in particular before all calls to scanf(3))
printf("Please enter your birth date: ");
fflush(NULL);
但你应该阅读 this C reference website, a good book about C programming such as Modern C, and the documentation of your C compiler (perhaps GCC) and debugger (perhaps GDB)。
考虑在编译器中启用所有警告和调试信息。使用 gcc
意味着使用 gcc -Wall -Wextra -g
进行编译
请注意 scanf(3) 可能会失败。
您的代码和问题肯定operating system具体。
在 Linux 考虑使用 ncurses (for a terminal interface) or GTK (for a graphical interface). Read also the tty demystified, then Advanced Linux Programming and syscalls(2) and termios(3)。
您也可以考虑使用 ANSI escape codes, but be aware that in 2020 UTF-8 should be used everywhere。
扩展我的评论...
您 运行 遇到的问题是您必须为每个输入按 Enter,这会在终端屏幕上写入一个换行符。你无法避免。
不幸的是,您无法用 '\b'
覆盖屏幕上的换行符;您只能退格到当前行的开头,不能退格到上一行。
你基本上不能用 vanilla C 做你想做的事——这种语言只能看到字节流,它没有“屏幕”的概念。
有一些 terminal control sequences 您可以在发送换行符后重新定位光标;我不知道这些对你的效果如何。
除此之外,您还需要使用 ncurses
.
这样的库
我想在一行中获取出生日期:
#include <stdio.h>
int main()
{
int BirthYear,BirthMonth,BirthDay;
printf("Please enter your birth date: ");
scanf("%d",&BirthYear);
printf("/");
scanf("%d",&BirthMonth);
printf("/");
scanf("%d",&BirthDay);
return 0;
}
这是我的输出:
Please enter your birth date: YYYY
/MM
/DD
但我想得到这样的东西:
Please enter your birth date: YYYY/MM/DD
在输出中,它在每个 scanf() 之后转到下一行而不使用 \n。 我使用 VS Code 进行 IDM。
#include <stdio.h>
int main()
{
int BirthYear,BirthMonth,BirthDay;
printf("Please enter your birth date: ");
scanf("%d/%d/%d",&BirthYear,&BirthMonth,&BirthDay);
return 0;
}
您可以从 scanf
中获取多个值,然后用您喜欢的任何文本分隔(在本例中为 /
s)。
您可以通过在 scanf
函数的格式说明符中添加 '/'
字符来明确指定应该用 '/'
字符分隔三个输入数字。
然后,您可以通过检查 scanf
返回的值(这将是成功扫描和分配的项目数)来确保用户输入有效;如果该值不是 3
,那么您将(可能)需要清除输入缓冲区中的任何 'leftover' 个字符,使用 getchar()
循环直到换行符(或 end-of-file ) 被发现:
#include <stdio.h>
int main()
{
int BirthYear, BirthMonth, BirthDay;
int nIns = 0, ch;
while (nIns != 3) {
printf("Enter D.O.B. (as YYYY/MM/DD): ");
nIns = scanf("%d/%d/%d", &BirthYear, &BirthMonth, &BirthDay);
while ((ch = getchar() != '\n') && (ch != EOF))
; // Clear remaining in-buffer on error
}
printf("Entered data were: %d %d %d!\n", BirthYear, BirthMonth, BirthDay);
return 0;
}
这是一个使用 ansi 控制字符的解决方法。我不会这样做,只是为了证明这是可能的:
#define PREVLINE "3[F"
#define MSG "Please enter your birth date: "
int main(void) {
int BirthYear,BirthMonth,BirthDay;
printf(MSG);
scanf("%d",&BirthYear);
printf(PREVLINE MSG "%d/", BirthYear);
scanf("%d",&BirthMonth);
printf(PREVLINE MSG "%d/%d/", BirthYear, BirthMonth);
scanf("%d",&BirthDay);
printf("You entered: %d/%d/%d\n", BirthYear, BirthMonth, BirthDay);
}
请注意,这不是便携式的。终端需要支持这个才能工作。据我所知,没有 100% 可移植的方法来实现这一点。
如果你真的想做这些东西,我建议你看看the ncurses library
注:
始终检查 scanf
的 return 值以检测错误。
注2:
在每个 printf
语句后添加 fflush(stdout);
可能是个好主意。
其实我今天又写了一篇关于ascii控制字符的回答。这可能很有趣:
您可以像
那样使用 fflush(3) (in particular before all calls to scanf(3))printf("Please enter your birth date: ");
fflush(NULL);
但你应该阅读 this C reference website, a good book about C programming such as Modern C, and the documentation of your C compiler (perhaps GCC) and debugger (perhaps GDB)。
考虑在编译器中启用所有警告和调试信息。使用 gcc
意味着使用 gcc -Wall -Wextra -g
请注意 scanf(3) 可能会失败。
您的代码和问题肯定operating system具体。
在 Linux 考虑使用 ncurses (for a terminal interface) or GTK (for a graphical interface). Read also the tty demystified, then Advanced Linux Programming and syscalls(2) and termios(3)。
您也可以考虑使用 ANSI escape codes, but be aware that in 2020 UTF-8 should be used everywhere。
扩展我的评论...
您 运行 遇到的问题是您必须为每个输入按 Enter,这会在终端屏幕上写入一个换行符。你无法避免。
不幸的是,您无法用 '\b'
覆盖屏幕上的换行符;您只能退格到当前行的开头,不能退格到上一行。
你基本上不能用 vanilla C 做你想做的事——这种语言只能看到字节流,它没有“屏幕”的概念。
有一些 terminal control sequences 您可以在发送换行符后重新定位光标;我不知道这些对你的效果如何。
除此之外,您还需要使用 ncurses
.