[英]C Programming - Allow / determine / check “space ( )” input in integer
首先,对不起我的英语不好,好的,请转到上面的问题。 在很多网站上,我都在网上冲浪很多有关此问题的参考,但是我没有找到正确的答案。
我正在尝试制作一个C程序,该程序可以确定用户是否输入了整数,如果用户未输入整数,则程序会重试提示用户输入整数,依此类推。 当我在条件语句上使用scanf()返回值时,一切正常,但问题是,当用户输入'whitespace / blankspace / space'(在ascii代码为&#32上)并按'enter'时,我的程序将保持运行状态等待用户输入一些字符或整数。
我只希望如果输入为'whitespace / blackspace / space',程序将重复提示用户输入整数或程序停止。
这是案例代码:
#include <stdio.h>
int main() {
int number, isInt;
printf("Input a number : ");
do {
if ((isInt = scanf("%d", &number)) == 0) {
printf("retry : ");
scanf("%*s");
} else if (number < 0) {
printf("retry : ");
}
} while (isInt == 0 || number < 0);
printf("%d\n", number);
return 0;
}
我是C语言的新手,对此感到很好奇。 我知道如果我对scanf()字符串使用%[^ \\ n] <-代码格式并将其转换为整数,我的意思是该程序将正确运行。 还有另一种使用%d代码格式解决此问题的方法吗? 或使用scanf()?
请帮助我打破好奇心,谨记:D
scanf
将忽略空格,并继续查找,直到找到非空格,然后再尝试进行转换。
我建议使用fgets获取输入行,然后使用sscanf处理。 像这样:
#include <stdio.h>
#include <stdlib.h>
int main() {
int number=-1;
printf("Input a number : ");
do {
char line[80];
if(!fgets(line,sizeof(line),stdin)){
printf("line read error\n");
exit(1);
}
if (sscanf(line,"%d", &number) !=1) {
printf("retry : ");
} else if (number < 0) {
printf("retry : ");
}
} while ( number < 0);
printf("%d\n", number);
return 0;
}
格式说明符'%* s'在遇到空格(制表符,空格,换行符)时将停止输入字符,因此,如果用户输入了这些字符中的任何一个,这些字符将不会被使用。
'%d'将消耗所有此类前导空白。
当用户输入一些“有效”数字时,该代码将进入“ else”语句
当用户输入诸如“ a”之类的ascii值时,“%d”将完成输入,并且代码将进入“ else”语句。 到那时,“ number”变量将不会被设置,因此“ number”将包含“ number”变量所在堆栈中碰巧的每个垃圾。 该“可能”恰好是大于0的整数。
从调用'scanf()'返回的值可以是0或1以外的值,例如EOF
“退格键”将由终端驱动程序占用,因此请不要访问该程序。
因此您的程序确实可以实现预期的功能,但可能并非您想要的。
%s
将跳过任何前导空格,然后读取非-空格字符,直到再次看到空格。 因此,该scanf( "*%s" );
调用将一直阻塞,直到看到至少一个非空白字符为止。
%[
转换说明符不会跳过任何前导空格,因此可以作为可接受的替代方法:
scanf( "%*[^\n]" );
尽管可以说,更好的方法是将所有输入读取为文本,然后使用strtol
将文本转换为目标类型,但这种方法在快速而肮脏的测试中“有效”。 这是我的意思的工作示例:
#include <stdio.h>
#include <stdlib.h>
#include <ctype.h>
#include <string.h>
#define BUF_SIZE 20
int main( void )
{
int value = -1;
char buf[BUF_SIZE];
do
{
printf( "Gimme a non-negative value: " );
if ( fgets( buf, sizeof buf, stdin ) )
{
char *newline = strchr( buf, '\n' );
if ( !newline )
{
printf( "Input too long for buffer, flushing..." );
while ( fgets( buf, sizeof buf, stdin ) && !strchr( buf, '\n' ) )
;
printf( "try again\n" );
}
else
{
*newline = 0; // Remove the newline character from the buffer
char *chk; // chk will point to the first character *not* converted
// by strtol. If that character is anything other
// than 0 or whitespace, then the input string was
// not a valid integer.
int tmp = (int) strtol( buf, &chk, 0 );
if ( *chk != 0 && !isspace( *chk ) )
{
printf( "%s is not a valid integer, try again\n", buf );
}
else if ( tmp < 0 )
{
printf( "%d is negative, try again\n", tmp );
}
else
{
value = tmp;
}
}
}
else
{
printf( "Input failure, bailing out completely\n" );
break;
}
} while ( value < 0 );
printf( "value is %d\n", value );
return 0;
}
而且,这是一个运行每个测试用例的示例:
$ ./format2
Gimme a non-negative value: Supercalifragilisticexpealidocious
Input too long for buffer, flushing...try again
Gimme a non-negative value: 123fgh
123fgh is not a valid integer, try again
Gimme a non-negative value: -12345
-12345 is negative, try again
Gimme a non-negative value: 1234
value is 1234
为了测试fgets
失败,我输入Ctrl - d发送EOF
:
$ ./format2
Gimme a non-negative value: Input failure, bailing out completely
value is -1
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.