gaa*_*kam 1 c io design-patterns interactive
根据C FAQ:http://c-faq.com/stdio/scanfprobs.html
我们不应该使用scanf
交互式输入输出,而是应该使用读取整行,fgets
然后尝试解析它sscanf
,如果sscanf
返回解析错误,则提示用户再次输入输入.
这个,IIUC,会导致这样的代码:
#include <stdio.h>
#include <stdbool.h>
#include <stdlib.h>
int main()
{
char inpbuff[5];
signed char n;
bool read_correctly = false;
while(!read_correctly) {
printf("Please enter an 8bit number: ");
if(fgets(inpbuff, sizeof(inpbuff), stdin) == NULL)
return EXIT_FAILURE;
if(sscanf(inpbuff, "%hhd", &n) == 1)
read_correctly = true;
}
printf("You have entered: %hhd\n", n);
return EXIT_SUCCESS;
}
Run Code Online (Sandbox Code Playgroud)
对我来说,如果用户键入的行超过提供的缓冲区大小,则此方法会产生问题fgets
.即使在上面的程序中,如果用户键入asdf
或者问题,也会出现问题asdf14
.
在这种情况下,理想情况下,我们应该忽略所有字符,直到我们看到'\n',忽略它\n
,然后再次要求用户提供他们的输入.这将导致这样的方法:
#include <stdio.h>
#include <stdbool.h>
#include <stdlib.h>
int main()
{
char inpbuff[5];
signed char n;
bool read_correctly = false;
while(!read_correctly) {
printf("Please enter an 8bit number: ");
switch(scanf("%hhd", &n)) {
case 1:
read_correctly = true;
break;
case 0: {
char sink;
do {
sink = fgetc(stdin);
if(sink == EOF)
return EXIT_FAILURE;
} while(sink != '\n');
break;
}
default:
return EXIT_FAILURE;
}
}
printf("You have entered: %hhd\n", n);
return EXIT_SUCCESS;
}
Run Code Online (Sandbox Code Playgroud)
我认为它必须是次优的,因为它与C FAQ推荐的相反!我绝对不认为自己比C FAQ作者更聪明.
那么,C中交互式输入/输出的典型处理如何?
你的版本错过了一个极端情况 - 假设我输入了1r4
.您的scanf
呼叫将成功转换并分配1
给n
,返回1表示成功,并留r4
在输入流中以填写下一个读取.理想情况下,你想1r4
完全拒绝.
这就是为什么建议将输入作为文本读取,然后处理该缓冲区.如果有人输入的行超过缓冲区的大小,你可以在输入阶段通过检查缓冲区中的换行来处理它 - 如果它不存在,则拒绝输入太大,然后读取并丢弃任何其他字符,直到你看到换行符.
while ( fgets( buffer, sizeof buffer, stdin ) )
{
char *newline = strchr( buffer, '\n' );
if ( !newline )
{
/**
* input too large for buffer, throw away current input, read and
* discard additional characters until we see the newline or EOF
*/
for ( int c = getchar(); c != EOF && c != '\n'; c = getchar() )
;
}
else
{
// process input buffer
}
}
Run Code Online (Sandbox Code Playgroud)
是的,在1分钟的痛苦中,C语言中的交互式输入定义了痛苦的屁股.你真的必须跳过所有这些篮球以防止输入错误.
你可以将呼叫防范scanf
到一定程度,但最终你可以毫不费力地进行自己的解析.
归档时间: |
|
查看次数: |
284 次 |
最近记录: |