我无法确定在主程序中输入多少个数字。 例如,我可能在数组中输入一个或两个数字。
float p[1];
for (int z = 0 ; z <=1 ; z++)
{
scanf("%f",&p[z]);
}
在这段代码中,如果我只输入一个数字,for循环将继续运行,直到我输入另一个数字。 我该怎么办?
答案 0 :(得分:3)
通常,用户必须告诉程序没有更多输入,通常是通过执行以下操作之一:
输入一个超出预期值范围的值(例如,如果您希望所有输入都大于0
,则输入值0
可能表示结束输入)。这通常不是最实用的方法,特别是对于浮点输入。
从键盘发出文件结束信号。在Linux上,通过键入Ctrl-D
来完成此操作,而在Windows上则通过键入Ctrl-Z
来完成。这种方法的优点是它适用于交互式输入和基于文件的输入。
scanf
函数返回成功转换和分配的次数;如果输入与转换说明符不匹配,则返回0,在文件结束或错误时返回EOF。这导致了如下逻辑:
float p[N]; // for some number N
size_t z = 0;
while ( z < N && scanf( "%f", &p[z] ) == 1 )
z++;
首先检查以确保z
小于N
;如果是这样,它将尝试将下一个输入读入p[z]
。如果读取成功(1次成功转换和分配),它将递增z
并再次循环。
如果读取失败(由于EOF或输入错误),它将退出循环。
修改强>
如果您在一行上输入多个值,另一种方法是将输入作为一行文本读取,然后解析出单个数字。这是一个例子:
#include <stdlib.h>
#include <stdio.h>
#include <string.h>
#include <ctype.h>
int main( void )
{
char input[SIZE+1]; // for some size SIZE, single line of text input,
// +1 for 0 terminator
float p[N]; // for some size N
size_t z = 0;
/**
* Instead of scanf, use fgets to read a line of input
* from the input stream. Go until z == N or
* there's no more input.
*/
while( z < N && fgets( input, sizeof input, stdin ) != NULL )
{
const char *delimiter = " \t";
/**
* Break the input line into *tokens* separated by spaces or tabs
* (note that this modifies the input buffer by overwriting
* space and tab characters with 0)
*/
char *token = strtok( input, delimiter );
/**
* Loop while z < N and token is not NULL.
*/
while ( z < N && token )
{
char *chk = NULL;
/**
* Convert the token (which is a string) to the
* equivalent floating-point value. If the token
* contains any characters that don't belong in a
* floating-point constant, the chk variable will be
* set to point to that character.
*/
double val = strtod( token, &chk );
/**
* On a successful conversion, chk should point to either
* a whitespace character or the 0 terminator.
*/
if ( *chk != 0 && !isspace( *chk ))
{
/**
* For this example we simply discard the bad input and keep processing
*/
fprintf( stderr, "%s is not a valid float value - discarding\n", token );
}
else
{
p[z++] = value;
}
/**
* NULL tells strtok to keep reading from the end of the
* previous token in the buffer
*/
token = strtok( NULL, delimiter );
}
}
/**
* Do something interesting with your p array
*/
return 0;
}
这样,如果您输入数据
1.0 2.0 3.0 4.0 ...
此代码将处理每个输入,直到它到达输入的末尾。
在此示例中未处理的一个边缘条件是,如果输入行大于SIZE
个字符,则最终会拆分标记。换句话说,您的缓冲区大小可以容纳80个字符,但最终输入90个字符,并且您的一个输入跨越了该边界。有几种方法可以解决这个问题,但我试图让这个例子尽可能简单。
如果你因为C中的交互式输入处理繁琐且容易出错而留下这个印象,那么你是对的。它是。我之前应该提到的一点是scanf
不是处理交互式输入的好工具;它缺少上面代码中的一些错误处理能力。