- html - 出于某种原因,IE8 对我的 Sass 文件中继承的 html5 CSS 不友好?
- JMeter 在响应断言中使用 span 标签的问题
- html - 在 :hover and :active? 上具有不同效果的 CSS 动画
- html - 相对于居中的 html 内容固定的 CSS 重复背景?
我的简单登录程序代码遇到了问题。我面临的问题是,当我使用开关盒或if语句(以管理员或用户身份登录)时,用户名的输入将被跳过并直接输入密码,无论我输入什么,它都会给我我的错误讯息。相反,我希望它先接收我的用户名,然后再接收密码。如果只有“管理员”或“用户”的代码,而只有一个,而没有多个代码,则它不能单独工作。请帮忙。注意:我正在为管理员和用户使用相同的功能,只是为了检查它是否有效。图为输出,我是C新手,所以可能是最小的术语?代码如下:
#include<stdio.h>
#include<conio.h>
#include<stdlib.h>
char username[18];
char pass[16];
void arequest()
{
printf("\nPlease Enter username:");
fflush(stdin);
gets(username);
printf("\nPlease Enter Password:");
fflush(stdin);
gets(pass);
}
void averify()
{
if (strcmp(username, "admin") == 0)
{
if (strcmp(pass, "apass") == 0)
{
printf("Successful Login");
_getch();
}
else
{
printf("Invalid Password");
_getch;
}
}
else
{
printf("Invalid Username");
_getch();
}
}
int choice;
int main()
{
printf("Welcome to Railway Reservation System");
printf("\n1.Admin \n2.User");
printf("\nPlease Enter your selection:");
scanf_s("%d", &choice);
if (choice == 1)
{
arequest();
averify();
}
else if (choice == 2)
{
arequest();
averify();
}
else
{
printf("Invalid Choice");
_getch();
return main;
}
return 1;
}
最佳答案
您正在使用fflush()
刷新输入流。 fflush(stdin)
在大多数情况下是未定义的行为,并且最多取决于实现。要清除输入流中的多余字符,请考虑编写如下这样的小函数:
void clear_stream(void)
{
int c;
while ((c = _getch()) != '\n' && c != EOF)
continue;
}
fflush()
的呼叫。您无需在
gets(username)
之后清除流,因为
gets()
会丢弃换行符。在
clear_stream()
中的此行之后添加对
main()
的呼叫:
scanf_s("%d", &choice);
scanf_s()
之后,输入流中可能会留有多余的字符,包括换行符,并且在尝试再次读取用户输入之前需要删除这些字符。在某些情况下,
scanf()_s
(和
scanf()
)将在读取输入时跳过初始空格,但
_getch()
和
getchar()
不会。这说明了使用
scanf()
的危险之一。
printf("\nPlease Enter your selection:");
scanf("%d", &choice);
clear_stream();
gets()
被认为是如此危险,以至于根本没有理由将其用于任何用途。请改用
fgets()
。
fgets()
确实保留换行符,而
gets()
在其中删除它,因此我经常使用安全的
gets()
编写自己的
fgets()
版本:
char * s_gets(char *st, int n)
{
char *ret;
int ch;
ret = fgets(st, n, stdin);
if (ret) {
while (*st != '\n' && *st != '\0')
++st;
if (*st)
*st = '\0';
else {
while ((ch = getchar()) != '\n' && ch != EOF)
continue; // discard extra characters
}
}
return ret;
}
conio.h
是非标准的,函数
_getch()
和
scanf_s()
也是非标准的。您应该使用
stdio.h
函数
getchar()
和
scanf()
。
scanf()
返回的值是成功分配的数量,您应该检查一下以确保输入符合预期。在您的程序中,如果用户在选择提示下输入字母,则不会进行分配,并且
choice
的值仍未初始化。该代码继续而不处理此问题。
choice
可以初始化为某个合理的值,例如
int choice = -1;
。或者,您可以检查
scanf()
的返回值以查看是否进行了赋值,然后进行相应的操作。
return
中
main()
正在1。除非出现错误,否则您应该
return
0。而且,如果选择无效,我会看到您
return
main
。也许您是要在这里
return
1?看来您忘记了
#include <string.h>
功能。
strcmp()
,
username
和
pass
是全局变量。这是一个坏习惯。这些应该在
choice
中声明,并根据需要传递给函数。
main()
全局常量
#define
和
MAXNAME
而不是硬编码数组维是一个好主意。
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#define MAXNAME 18
#define MAXPASS 16
void clear_stream(void)
{
int c;
while ((c = getchar()) != '\n' && c != EOF)
continue;
}
char * s_gets(char *st, int n)
{
char *ret;
int ch;
ret = fgets(st, n, stdin);
if (ret) {
while (*st != '\n' && *st != '\0')
++st;
if (*st)
*st = '\0';
else {
while ((ch = getchar()) != '\n' && ch != EOF)
continue; // discard extra characters
}
}
return ret;
}
void arequest(char username[MAXNAME], char pass[MAXPASS])
{
printf("\nPlease Enter username:");
s_gets(username, MAXNAME);
printf("\nPlease Enter Password:");
s_gets(pass, MAXPASS);
}
void averify(char username[MAXNAME], char pass[MAXPASS])
{
if (strcmp(username, "admin") == 0)
{
if (strcmp(pass, "apass") == 0)
{
printf("Successful Login");
getchar();
}
else
{
printf("Invalid Password");
getchar();
}
}
else
{
printf("Invalid Username");
getchar();
}
}
int main(void)
{
char username[MAXNAME];
char pass[MAXPASS];
int choice;
printf("Welcome to Railway Reservation System");
printf("\n1.Admin \n2.User");
printf("\nPlease Enter your selection: ");
if (scanf("%d", &choice) == 1) {
clear_stream();
if (choice == 1)
{
arequest(username, pass);
averify(username, pass);
}
else if (choice == 2)
{
arequest(username, pass);
averify(username, pass);
}
else
{
printf("Invalid Choice: %d\n", choice);
getchar();
return 1;
}
} else {
clear_stream(); // stream has not yet been cleared
printf("Nonnumeric input");
getchar();
}
return 0;
}
MAXPASS
在Visual Studio中引起了问题。显然,Visual Studio尝试强制使用
scanf()
。此功能的问题不在于它本身是不好的,还在于它是非标准的。一种解决方案可能是使用已经添加到代码中的
scanf_s()
函数将用户选择读入字符缓冲区,然后使用
s_gets()
提取输入。这样做的优点是,无需在
sscanf()
之后调用
clear_stream()
函数,因为
s_gets()
会在其自身之后清除,因此现在可以将
s_gets()
函数从程序中完全删除。只需在
clear_stream()
中进行少量更改即可完成:
char choice_buffer[10];
int choice;
...
if (s_gets(choice_buffer, sizeof(choice_buffer)) &&
sscanf(choice_buffer, "%d", &choice) == 1) {
if (choice == 1)
...
} else {
printf("Nonnumeric input");
getchar();
}
main()
最多读取用户输入到
s_gets()
的一行的前9个字符(在这种情况下),该数组将容纳
choice_buffer
s(
char
中的空间超出了所需的空间)按住一个数字和一个
choice_buffer
)。如果存在错误,则
'\0'
返回
s_gets()
指针,否则返回指向
NULL
的第一个
char
的指针。如果
choice_buffer
的返回值不是-
s_gets()
,则
NULL
将缓冲区中存储的第一个
sscanf()
分配给
int
。如果在字符串中未找到
choice
,则
int
返回值0,从而导致条件测试失败。
关于c - 跳过第一个输入,直接转到下一个输入,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/41158761/
我的算法- private static MyList skip$DeleteItem(MyList L , int M , int N){ MyList curr = L; MyLi
我正在 SWI-Prolog 下开发,但我的目标是 Erlog (https://github.com/rvirding/erlog)。我需要一种使用非标准 Prolog 语法的方法。 有没有办法
我正在尝试从应用程序下载一大堆文件。它的shell命令是“下载文件名”。 我有一个文本文件,其中包含必须下载的所有文件名。我要做的就是运行一个脚本/命令,以便在执行上述命令时 1.从文本文件中提取文件
我试图循环遍历所有用户的评论,但使用 if 语句查找特定值。问题是我的应用程序崩溃了,因为一些用户没有发表评论,因此我得到“无法读取‘收集’未定义的属性”。如何跳过 if 语句的未定义值?代码如下:
我们有按年份分区的索引,例如: items-2019 items-2020 考虑以下数据: POST items-2019/_doc { "@timestamp": "2019-01-01" }
我只是编写一个页面来按实体编号查看每个 ASCII 条目,我想知道是否有一种更简单/更干净的方法来跳过不需要的数字。 var x = new Ar
我希望能够普遍使用重复条目,但也能够跳过特定日期。例子: ** TODO swim practice SCHEDULED 但是,我提前知道 2013-12-25 不会有练习。但是,当我将项目标
如何跳过像这样的 for 循环的一次迭代: for (int i = 65; i <= 90; i++) { if (!(i == 73)) { uniq.add((char) i);
这个问题已经存在: Scanner issue when using nextLine after nextXXX [duplicate] 已关闭 9 年前。 ask=1; while(ask==1)
我在使用一个程序时遇到了一些麻烦,我应该允许用户在程序中输入任意数量的数字,直到他们不再想要为止。然后程序应该计算输入数字的平均值和最大值。我哪里做错了? import java.util.Scann
我有一个名为segments的 Sprite 数组,我想在每个循环中跳过segments的第一个元素。我目前正在这样做: var first = true; for each (var segment
我目前正在编写一个 for 循环来遍历包含 38 个元素的 2D。然而,其中一些元素为空,我希望 for 循环简单地跳过它们(因为在我正在解决的难题中,它们没有与它们相关的移动)。快速搜索表明,我可以
我想使用pre-commit处理我的 git 项目的 git hooks。但是,当我使用它时,git commit 命令不断跳过 unittest 执行: (smartexchange) trnboo
这个问题在这里已经有了答案: Does scanf() take '\n' as input leftover from previous scanf()? (1 个回答) 关闭 9 年前。 我正在
我正在迭代 csv 文件中的每一行,并仅选择/计算满足条件的行。但是,当连续出现错误时,它会停止循环。有没有办法告诉 python 跳过错误并移动到下一行?我使用了 try 函数但没有工作。我的代码是
感谢您提供的优秀示例,我试过了,它按我的预期工作。很高兴看到有人了解问题的本质。但是,我认为我应该用 Lift 标记问题,因为我正在使用 Lift 框架,这就是(仍然)发生这个问题的地方(尽管我仍然认
大家好,我正在编写一个算法来从 NodeTree 中删除具体分支(例如 DSF)。如果您选择 Node 的名称,算法将检查该 Node 是否是其他 Node 的父 Node ;如果是,它会获取该 No
附有代码和输出。 基本上它是第二次跳过我的输入。就像我启动代码一样,它让我输入一个选项,然后第二次跳过输入,直接转到开关的默认情况。 然后第三次它就会允许我输入。不明白为什么。 任何帮助将不胜感激。
我在 JavaScript 中有一个 for 循环,它会定期跳过间隔,但我无法确定原因。 console.log(parseInt($('input.num-to-add').val())); num
我正在 JasperSoft 中填写参数。在我的报告中我有参数:参数_1、参数_2、参数_3 int a; for (a = 0; a < headers.length; a++) {
我是一名优秀的程序员,十分优秀!