我有一个程序,提示用户输入三个浮点数,如果这些数字不是正数或不是数字,则打印出"Invalid number"
这是用goto
循环完成的程序的一部分我想摆脱它。
float array[n][3];
int i;
for(i = 0;i<n;i++){
one:
printf( "Please enter first number: ");
scanf("%f", &array[i][0]);
while(array[i][0]<0){
printf("Invalid number: ");
goto one;
}
two:
printf("Please enter second number: ");
scanf("%f", &array[i][1]);
while(array[i][1]<0){
printf("Invalid number: ");
goto two;
}
three:
printf("Please enter third number: ");
scanf("%f", &array[i][2]);
while(array[i][1]<0){
printf("Invalid number: ");
goto three;
}
}
如何转换循环goto one
,goto two
和goto three
;在一个while循环,或某种循环?
答案 0 :(得分:1)
查看我的更改。我不仅修改了goto
案例:
double array[n][3];
int i, j;
char * fst[] = { "first", "second", "third" };
for( i = 0; i < n; i++ )
{
for ( j = 0; j < 3; j++ )
{
while ( 1 )
{
printf( "Please enter %s number: ", fst[j] );
scanf( "%lf", &array[i][j] );
if ( array[i][j] < 0 )
printf("Invalid number.\n");
else break;
}
}
}
类似的块与循环和单词数组相结合。 double
优于float
,除非RAM很低(嵌入式系统)。 goto
已转换为while
循环和break
。我想你对负数说“无效数字”,而不是scanf
失败。如果检查失败scanf
,则可将其修改为if ( scanf( "%lf", &array[i][j] ) < 1 ) ...
。
答案 1 :(得分:1)
您可以将其转换为do { ... } while(...);
示例:
one:
printf( "Please enter first number: ");
scanf("%f", &array[i][0]);
while(array[i][0]<0){
printf("Invalid number: ");
goto one;
}
要
do
{
printf ("Please enter first number: ");
scanf ("%f", &array[i][0]);
if (array[i][0] < 0)
{
printf ("Invalid number: ");
}
}
while (array[i][0] < 0);
答案 2 :(得分:0)
你可以这样做
for(i = 0;i<n;i++){
while(printf( "Please enter first number: ")>0 && scanf("%f", &array[i][0])==1 && array[i][0]<0 && printf("Invalid number: ") );
while(printf( "Please enter second number: ")>0 && scanf("%f", &array[i][1])==1 && array[i][1]<0 && printf("Invalid number: "));
while(printf( "Please enter third number: ")>0 && scanf("%f", &array[i][2])==1 && array[i][2]<0 && printf("Invalid number: ") );
}
Short circuit evaluation在这里受益。
printf()
将返回打印的字符数,如果成功则返回大于零。
如果printf()
成功,则执行scanf()
,返回成功分配的数量。在这种情况下,如果成功则应为1
。
如果printf()
和scanf()
都成功且array[i][j]
小于零,则显示错误消息printf()
并重复循环。
您可以将这些while
循环设为
while(printf( "Please enter third number: ")>0 && scanf("%f", &array[i][2])==1 && array[i][2]<0)
{
printf("Invalid number: ")
}
使其更具可读性。
编辑:
如果输入不是有效数字,scanf()
将不会读入变量,因为格式说明符为%f
。
这可能会导致问题,因为无效输入将在输入缓冲区中保持未使用状态。您需要清除输入缓冲区。
像
这样的东西int ch;
while( (ch=getch())!=EOF && ch!='\n' );
可能用于从输入缓冲区消耗直到换行符。有关详情,请参阅here。
错误时, getchar()
会返回EOF
。请注意,getchar()
返回转换为int 的无符号字符。
要包含此功能,您可以将这些while
循环修改为
int ch;
while(printf( "Please enter third number: ")>0 && scanf("%f", &array[i][2])==1 && array[i][2]<0)
{
printf("Invalid number: ")
while( (ch=getch())!=EOF && ch!='\n' );
}
答案 3 :(得分:0)
避免goto
通常是一个好主意(尽管存在一些可接受的用途)。其他要避免的事情:
解决上述所有问题的一种可能解决方案:
#include <stdio.h>
float enter_float (size_t n)
{
const char* STR_NUMBER[] = { "first", "second", "third" };
float result;
printf("Please enter %s number: ", STR_NUMBER[n]);
scanf("%f", &result);
return result;
}
int main (void)
{
size_t n=3;
float array[n];
for(size_t i=0; i<n; i++)
{
float input;
while( (input = enter_float(i)) < 0.0f)
{
printf("Invalid number\n");
}
array[i] = input;
}
}
(理想情况下,代码还应检查scanf的结果,并通过指定scanf应读取的项目数来确保没有缓冲区溢出。)