有一些问题。
第一个scanf 不会检查数字中的语法错误,并且可能会在流中留下换行符并混淆第二个scanf
secondscanf可能不会从流中删除换行符,所以在第二次循环迭代中,firstscanf可能有问题。
虽然它可能可以修复/扭曲 scanf 做你想做的事,但我会遵循 clang 的警告并使用 strtof。
这是重构为使用fgets 和strtof 的代码。有注释:
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
//#include <rpcndr.h>
// lineget -- get a line from user with prompt
// RETURNS: pointer to buffer (NULL means EOF)
char *
lineget(char *buf,size_t len,const char *prompt)
{
char *cp;
// output prompt to user
puts(prompt);
fflush(stdout);
do {
// get an input line
cp = fgets(buf,len,stdin);
// got EOF
if (cp == NULL)
break;
// strip newline
buf[strcspn(buf,"\n")] = 0;
} while (0);
return cp;
}
int
main(void)
{
float num1, num2, answer;
char *cp;
char buf[1000];
int err;
char operator;
while (1) {
cp = lineget(buf,sizeof(buf),
"Enter First Number, operator, second number:");
if (cp == NULL)
break;
// get the first number
num1 = strtof(cp,&cp);
// get the operator
// NOTE: this could be a syntax error for the first number -- we'll
// check that below in the switch
operator = *cp;
if (operator != 0)
++cp;
// get second number and check for syntax error
num2 = strtof(cp,&cp);
if (*cp != 0) {
printf("ERROR trailing '%s'\n",cp);
continue;
}
err = 0;
switch (operator) {
case '*':
answer = (num1 * num2);
break;
case '/':
answer = (num1 / num2);
break;
case '+':
answer = num1 + num2;
break;
case '-':
answer = num1 - num2;
break;
default:
err = 1;
break;
}
// we got a bad operator (or syntax error in first number)
if (err) {
printf("ERROR unknown operator '%c'\n",operator);
continue;
}
printf("%f\n", answer);
cp = lineget(buf,sizeof(buf),"Do You Want To Try It Again(y/n)?");
if (cp == NULL)
break;
if (buf[0] == 'n')
break;
}
return 0;
}
更新:
上面的代码将检测到大多数错误。这是一个增强版本,它进行了更明确的检查:
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
//#include <rpcndr.h>
// lineget -- get a line from user with prompt
// RETURNS: pointer to buffer (NULL means EOF)
char *
lineget(char *buf,size_t len,const char *prompt)
{
char *cp;
// output prompt to user
puts(prompt);
fflush(stdout);
do {
// get an input line
cp = fgets(buf,len,stdin);
// got EOF
if (cp == NULL)
break;
// strip newline
buf[strcspn(buf,"\n")] = 0;
} while (0);
return cp;
}
int
main(void)
{
float num1, num2, answer;
char *cp;
char *bp;
char buf[1000];
int err;
char operator;
while (1) {
bp = lineget(buf,sizeof(buf),
"Enter First Number, operator, second number:");
if (bp == NULL)
break;
// get the first number
num1 = strtof(bp,&cp);
// ensure we got at least a digit
// NOTE: this will detect:
// ""
// "j"
if (cp == bp) {
printf("ERROR no first number specified\n");
continue;
}
// get the operator
// NOTE: this could be a syntax error for the first number -- we'll
// check that below in the switch
operator = *cp;
// no operator specified
if (operator == 0) {
printf("ERROR no operator specified\n");
continue;
}
// skip over the operator
bp = ++cp;
// get second number and check for syntax error
num2 = strtof(bp,&cp);
if (*cp != 0) {
printf("ERROR trailing '%s'\n",cp);
continue;
}
// we need at least one digit (e.g.):
// we want to reject: 23+ and ensure we have [at least] 23+0
// this will detect 23+k
if (cp == bp) {
printf("ERROR no second number specified\n");
continue;
}
err = 0;
switch (operator) {
case '*':
answer = (num1 * num2);
break;
case '/':
answer = (num1 / num2);
break;
case '+':
answer = num1 + num2;
break;
case '-':
answer = num1 - num2;
break;
default:
err = 1;
break;
}
// we got a bad operator (or syntax error in first number)
if (err) {
printf("ERROR unknown operator '%c'\n",operator);
continue;
}
printf("%f\n", answer);
cp = lineget(buf,sizeof(buf),"Do You Want To Try It Again(y/n)?");
if (cp == NULL)
break;
if (buf[0] == 'n')
break;
}
return 0;
}