我在C中验证单字符scanf输入时遇到问题而我找不到现有的解决方案...
场景是:一种方法只需要一个字母' char'键入输入然后验证此输入,如果不满足条件,则弹出错误消息并重新输入,否则返回此字符值。
我的代码是:
char GetStuff(void)
{
char c;
scanf("%c", &c);
while(c != 'A' || c != 'P')
{
printf("invalid input, enter again (A for AM or P for PM): ");
scanf ("%c", &dtChar);
}
return c;
}
然而,无论输入什么输入,我都得到了无限循环的错误信息。我读了一些其他帖子并猜测%c说明符在我点击时没有自动摆脱换行符的问题进入,到目前为止我尝试过:
在%c之前/之后放置一个空格,如:
scanf(" %c", &c);
编写单独的方法或在此GetStuff
方法中包含以清除换行符,如:
void cleanBuffer(){
int n;
while((n = getchar()) != EOF && n != '\n' );
}
有人可以帮我解决这个问题吗?提前谢谢。
答案 0 :(得分:1)
在内部循环中,你正在dtChar
中输入,但你的循环条件检查循环中没有更新的变量c
,这会导致无限循环
你也会改变你的状况
while(c != 'A' || c != 'P')
到
while(c != 'A' && c != 'P')
如果您希望用户输入“A' A'或者' P'
答案 1 :(得分:1)
#include <stdio.h>
char GetStuff(void) {
char c;
scanf("%c", &c);
getchar();
while ((c != 'A') && (c != 'a') && (c != 'P') && (c != 'p')) {
printf("invalid input, enter again (A for AM or P for PM): ");
scanf ("%c", &c);
getchar();
}
return c;
}
int main(void) {
printf("Calling GetStuff()...\n");
char x = GetStuff();
printf("User entered %c\n", x);
return 0;
}
You are using while (c != 'A' || c != 'P')
as your loop conditional, but this will always return true. What you meant to use is the && "and" operator, instead of the || "or" operator.
Also, call getchar()
after your scanf statements, to capture the newline. This should work the way you want it to.
答案 2 :(得分:1)
Please consider the following snippet:
#include <stdio.h>
#include <ctype.h>
char GetStuff(void)
{
char c;
do {
printf("Please enter A for AM or P for PM: ");
scanf ("%c", &c);
// clean input buffer (till the end of line)
while(getchar()!='\n');
} while(toupper(c) != 'A' && toupper(c) != 'P');
return c;
}
int main(void)
{
printf("Your input is'%c'\n", GetStuff());
return 0;
}
Note the points:
while(c != 'A' || c != 'P')
will be always true (just because one character cannot be 'A' and 'P' at the same time), so use while(c != 'A' && c != 'P')
insteadscanf
if you use do..while
loopscanf
it is recommended to clean all characters from buffer, e.g. with while(getchar()!='\n');
(this will clean all input including incorrect and redundant characters)toupper
to avoid making 4 comparison (actually single c=toupper(c)
inside loop can minimize your while as while(c != 'A' && c != 'P')
)UPDATE:
To add message "Invalid input" and adding some other useful improvement subjected befor... new code is as:
#include <stdio.h>
#include <ctype.h>
void CleanBuffer(){
int n;
while((n = getchar()) != EOF && n != '\n' );
}
char GetStuff(void)
{
char c;
do {
printf("Please enter A for AM or P for PM: ");
scanf (" %c", &c);
c = toupper(c); // here letter become uppercase
CleanBuffer();
} while( (c != 'A' && c != 'P')?printf("Invalid input! "):0 );
return c;
}
int main(void)
{
printf("You have entered: %c\n", GetStuff());
return 0;
}
Note: function will return 'A' or 'P' in uppercase, so if this is not needed change the code as in example before update (use two toupper
and do not change c
after scanf
). Also you can use tolower
as an option (of course with comparing to 'a'
and 'p'
).
答案 3 :(得分:0)
Another possible solution. As others mentioned the condition was to be done with &&. Anyway the big problem is how to remove what's left on the console input line. Since the console works by lines, we remove everything up to the next using System.Diagnostics;
public static class StorageEmulatorHelper {
/* Usage:
* ======
AzureStorageEmulator.exe init : Initialize the emulator database and configuration.
AzureStorageEmulator.exe start : Start the emulator.
AzureStorageEmulator.exe stop : Stop the emulator.
AzureStorageEmulator.exe status : Get current emulator status.
AzureStorageEmulator.exe clear : Delete all data in the emulator.
AzureStorageEmulator.exe help [command] : Show general or command-specific help.
*/
public enum StorageEmulatorCommand {
Init,
Start,
Stop,
Status,
Clear
}
public static int StartStorageEmulator() {
return ExecuteStorageEmulatorCommand(StorageEmulatorCommand.Start);
}
public static int StopStorageEmulator() {
return ExecuteStorageEmulatorCommand(StorageEmulatorCommand.Stop);
}
public static int ExecuteStorageEmulatorCommand(StorageEmulatorCommand command) {
var start = new ProcessStartInfo {
Arguments = command.ToString(),
FileName = @"C:\Program Files (x86)\Microsoft SDKs\Azure\Storage Emulator\AzureStorageEmulator.exe"
};
var exitCode = executeProcess(start);
return exitCode;
}
private static int executeProcess(ProcessStartInfo startInfo) {
int exitCode = -1;
try {
using (var proc = new Process {StartInfo = startInfo}) {
proc.Start();
proc.WaitForExit();
exitCode = proc.ExitCode;
}
}
catch {
//
}
return exitCode;
}
}
. If the user already left something on the input line before calling '\n'
, it would be useful to add a call to GetStuff()
before the while loop.
In general I suggest to start with a SkipRestOfTheLine()
loop, before making it nicer (such as in the while(1)
you posted).
cleanBuffer()
答案 4 :(得分:-1)
try this,
char GetStuff(void)
{
char c;
scanf("%c", &c);
while (((c != 'A') || (c != 'a')) && ((c != 'P') || (c != 'p'))==1)
{
printf("invalid input, enter again (A for AM or P for PM): ");
scanf ("%c", &dtChar);
}
return c;
}
I hope this works, some time because of not given proper bracket it is stuck in the loop.