C 编程 - 允许/确定/检查 "space ( )" 整数输入
C Programming - Allow / determine / check "space ( )" input in integer
首先,抱歉我的英语不好,好吧,转到上面的这个问题。关于这个问题,我在很多网站上浏览了很多以供参考,但我还没有找到正确的答案。
我正在尝试制作一个 C 程序,该程序可以确定用户是否输入了整数,如果用户没有输入整数,则程序会重试提示用户输入整数,依此类推.当我在条件语句上使用 scanf() return 值时一切正常,但问题是,当用户输入 'whitespace/blankspace/space'(ASCII 码为 )并按 '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语言的新手,对此很好奇。我知道如果我使用 %[^\n] <-- scanf() 字符串的代码格式并将其转换为整数,我所指的程序将 运行 正确。还有另一种方法可以使用 %d 代码格式来解决这个问题吗?或使用 scanf() ?
请帮助我打破我的好奇心,问候 :D
scanf
将忽略白色 space 并继续寻找直到找到非白色 space,然后再尝试进行转换。
我建议使用 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”在遇到白色 space(制表符、space、换行符)时将停止输入字符,因此如果用户输入任何这些字符,他们将不会被消耗掉。
'%d' 将消耗所有此类领先的白色 space。
当用户输入一些 'valid' 数字时,代码将跳转到 'else' 语句
当用户输入一些 ascii 值时,例如 'a' 然后 '%d' 将完成输入,代码将进入 'else' 语句。
那时,'number'变量还没有设置
所以 'number' 将包含碰巧在 'number 变量所在的堆栈中的每个垃圾。
那'may'恰好是一个大于0的整数。
调用 'scanf()' 返回的值可以是 0 或 1 以外的值,例如 EOF
'backspace' 将被终端驱动程序消耗,因此永远不会到达程序。
因此您的程序完全符合预期,但可能不是您想要的。
%s
将跳过任何前导空格,然后读取 非-空格字符,直到它再次看到空格。因此,scanf( "*%s" );
调用将阻塞,直到它看到至少一个非空白字符。
%[
转换说明符 不会 跳过任何前导空格,因此这可能是一个可接受的替代:
scanf( "%*[^\n]" );
这个 "works" 在一个快速而肮脏的测试中,虽然说实话更好的方法是将所有输入读取为文本,然后使用 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
首先,抱歉我的英语不好,好吧,转到上面的这个问题。关于这个问题,我在很多网站上浏览了很多以供参考,但我还没有找到正确的答案。
我正在尝试制作一个 C 程序,该程序可以确定用户是否输入了整数,如果用户没有输入整数,则程序会重试提示用户输入整数,依此类推.当我在条件语句上使用 scanf() return 值时一切正常,但问题是,当用户输入 'whitespace/blankspace/space'(ASCII 码为 )并按 '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语言的新手,对此很好奇。我知道如果我使用 %[^\n] <-- scanf() 字符串的代码格式并将其转换为整数,我所指的程序将 运行 正确。还有另一种方法可以使用 %d 代码格式来解决这个问题吗?或使用 scanf() ?
请帮助我打破我的好奇心,问候 :D
scanf
将忽略白色 space 并继续寻找直到找到非白色 space,然后再尝试进行转换。
我建议使用 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”在遇到白色 space(制表符、space、换行符)时将停止输入字符,因此如果用户输入任何这些字符,他们将不会被消耗掉。
'%d' 将消耗所有此类领先的白色 space。
当用户输入一些 'valid' 数字时,代码将跳转到 'else' 语句
当用户输入一些 ascii 值时,例如 'a' 然后 '%d' 将完成输入,代码将进入 'else' 语句。 那时,'number'变量还没有设置 所以 'number' 将包含碰巧在 'number 变量所在的堆栈中的每个垃圾。 那'may'恰好是一个大于0的整数。
调用 'scanf()' 返回的值可以是 0 或 1 以外的值,例如 EOF
'backspace' 将被终端驱动程序消耗,因此永远不会到达程序。
因此您的程序完全符合预期,但可能不是您想要的。
%s
将跳过任何前导空格,然后读取 非-空格字符,直到它再次看到空格。因此,scanf( "*%s" );
调用将阻塞,直到它看到至少一个非空白字符。
%[
转换说明符 不会 跳过任何前导空格,因此这可能是一个可接受的替代:
scanf( "%*[^\n]" );
这个 "works" 在一个快速而肮脏的测试中,虽然说实话更好的方法是将所有输入读取为文本,然后使用 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