我正在尝试编写一个简单的C程序。输入格式如下:
Enter a: <a>
我想输入a,b,c和d但是scanf对c和d不起作用,程序在该点崩溃。
#include <stdio.h>
#include <math.h>
int main(){
int a, b, c, d;
char ch;
printf("Enter a:");
scanf("%c%d%c", &ch, &a, &ch);
printf("Enter b:");
scanf("%c%d%c", &ch, &b, &ch);
printf("Enter c:");
scanf("%c%d%c", &ch, &c, &ch);
printf("Enter d:");
scanf("%c%d%c", &ch, &d, &ch);
double ans;
ans=(a*b/c + c*d/a)/(b*a/c + d*b/a);
ans=fabs(ans);
printf("Formula 1 result = <%lf>", ans);
return 0;
}
答案 0 :(得分:1)
double ans;
ans=(a*b/c + c*d/a)/(b*a/c + d*b/a);
C语言在确定其类型时不会考虑对结果所做的操作。因此,将此操作的结果分配给double
这一事实对计算结果的方式没有任何影响,它只是将整数结果转换为double。当你用整数除整数时,你得到整数除法。
你可以这样做:
ans=(a*1.0*b/c + c*1.0*d/a)/(b*1.0*a/c + d*1.0*b/a);
乘以非整数强制使用非整数乘法,加法和除法。
答案 1 :(得分:1)
有3种格式转换说明符,不会跳过前导空格。它们是%c
(您正在使用),%[…]
次扫描集和%n
。
键入时:
Enter a:<1>
Enter b:<2>
第一个<
满足第一个%c
; 1
与%d
匹配,>
与第二%c
匹配,所以到目前为止一切正常。
然而,第二批输入从第一行读取换行符到第一行%c
,然后无法将<
转换为整数并停止,留下<
用于下一个要处理的输入。
提供了Enter c:
提示,但处理了<2>
因为格式正确,因此提供了Enter d:
提示。
有多种方法可以解决此问题,包括:
%c
之前插入空格。这将跳过空格,包括换行符,并为您提供预期的行为。这可能是最简单的解决方法。sscanf()
来处理它们。这通常是最好的解决方案。 (使用fgets()
读取该行。)在任何一种情况下,检查scanf()
族函数是否返回正确的值(3)。并使用两个变量int c1, c2;
来读取字符并验证用户输入了您需要的内容。
最低限度的修正是:
#include <math.h>
#include <stdio.h>
#include <stdlib.h>
int main(void)
{
int a, b, c, d;
char c1, c2;
printf("Enter a: ");
if (scanf(" %c%d%c", &c1, &a, &c2) != 3 || c1 != '<' || c2 != '>')
fprintf(stderr, "Bogus input!\n"), exit(1);
printf("Enter b: ");
if (scanf(" %c%d%c", &c1, &b, &c2) != 3 || c1 != '<' || c2 != '>')
fprintf(stderr, "Bogus input!\n"), exit(1);
printf("Enter c: ");
if (scanf(" %c%d%c", &c1, &c, &c2) != 3 || c1 != '<' || c2 != '>')
fprintf(stderr, "Bogus input!\n"), exit(1);
printf("Enter d: ");
if (scanf(" %c%d%c", &c1, &d, &c2) != 3 || c1 != '<' || c2 != '>')
fprintf(stderr, "Bogus input!\n"), exit(1);
double ans;
ans=(a*b/c + c*d/a)/(b*a/c + d*b/a);
ans=fabs(ans);
printf("Formula 1 result = <%lf>\n", ans);
return 0;
}
我在if
语句之后对逗号运算符很懒。但是,使用函数来管理输入会更好:
#include <math.h>
#include <stdio.h>
#include <stdlib.h>
static void get_number(int *var, const char *name)
{
char c1, c2;
printf("Enter %s: ", name);
if (scanf(" %c%d%c", &c1, var, &c2) != 3 || c1 != '<' || c2 != '>')
{
fprintf(stderr, "Bogus input!\n");
exit(1);
}
}
int main(void)
{
int a, b, c, d;
get_number(&a, "a");
get_number(&b, "b");
get_number(&c, "c");
get_number(&d, "d");
double ans;
ans=(a*b/c + c*d/a)/(b*a/c + d*b/a);
ans=fabs(ans);
printf("Formula 1 result = <%lf>\n", ans);
return 0;
}
最好还是使用:
#include <math.h>
#include <stdio.h>
#include <stdlib.h>
static int get_number(const char *name)
{
char buffer[4096];
printf("Enter %s: ", name);
if (fgets(buffer, sizeof(buffer), stdin) == 0)
{
fprintf(stderr, "EOF or error on input\n");
exit(1);
}
char c1, c2;
int val;
if (sscanf(buffer, " %c%d%c", &c1, &val, &c2) != 3 || c1 != '<' || c2 != '>')
{
/* buffer contains a newline unless you typed more than 4095 characters before the newline */
fprintf(stderr, "Bogus input (does not match <number>): %s", buffer);
exit(1);
}
return val;
}
int main(void)
{
int a = get_number("a");
int b = get_number("b");
int c = get_number("c");
int d = get_number("d");
double ans = fabs((a*b/c + c*d/a) / (b*a/c + d*b/a));
printf("Inputs: a = %d, b = %d, c = %d, d = %d\n", a, b, c, d);
printf("Formula 1 result = <%lf>\n", ans);
return 0;
}
请注意代码如何使用fgets()
加sscanf()
,这意味着错误消息可以告诉用户他们输入的内容不是预期的内容。它还使用该函数返回值,从而显示更简单的代码。输出包括检查的输入值。您的提交系统可能不需要这样做,但在您开发代码时它肯定会对您有所帮助。
您可以进行升级以处理double
值作为输入;这并不难。