如何接受作为一种数据类型并使用C中的函数存储在定义的结构中?

如何接受作为一种数据类型并使用C中的函数存储在定义的结构中?,c,struct,C,Struct,我有麻烦了,返回我定义的结构,我的函数扫描 从输入源输入一个用科学记数法表示正数的字符串,并将其分解为组件以存储在scinot结构中。示例输入为0.25000e4 #include <stdio.h> #include <stdlib.h> #include <math.h> typedef struct{ double mantissa; int exp; }sci_not_t;

我有麻烦了,返回我定义的结构,我的函数扫描 从输入源输入一个用科学记数法表示正数的字符串,并将其分解为组件以存储在scinot结构中。示例输入为0.25000e4

  #include <stdio.h>
    #include <stdlib.h>
    #include <math.h>

    typedef struct{
        double mantissa;
        int exp;
    }sci_not_t;

    int scan_sci (sci_not_t *c);

    int main(void){

        sci_not_t inp1, inp2;

        printf("Enter the mantissa in the range [0.1, 1.0) then its exponent: ");
        scan_sci(&inp1);
        printf("Enter second number with same specifications as above: ");
        scan_sci(&inp2);






      system("PAUSE");  
      return 0;
    }

    int scan_sci (sci_not_t *c){

        int status;
        double a;
        int b;

        status = scanf("%lf %d", &c->mantissa, &c->exp);

        a = c->mantissa;
        b = c->exp;
        *c = pow(a,b);

        if (status == 2 && (c->mantissa >= 0.1 && c->mantissa < 1.0) ){
            status = 1;
        }else{
            printf("You did not enter the mantissa in the correct range \n");
            status = 0;
        }


        return (status);
    }

    sci_not_t sum(sci_not_t c1, sci_not_t c2){

        return c1 + c2;
    }

    sci_not_t product(sci_not_t c1, sci_not_t c2){

        return c1 * c2;
    }
#包括
#包括
#包括
类型定义结构{
双尾数;
国际贸易;
}科学不是;
int扫描sci(sci非t*c);
内部主(空){
sci非inp1,inp2;
printf(“输入范围为[0.1,1.0]的尾数,然后输入其指数:”);
扫描sci和inp1;
printf(“输入与上述规格相同的第二个数字:”);
扫描sci和inp2;
系统(“暂停”);
返回0;
}
整数扫描sci(sci非t*c){
智力状态;
双a;
int b;
状态=scanf(“%lf%d”,&c->尾数,&c->exp);
a=c->尾数;
b=c->exp;
*c=功率(a,b);
如果(状态==2&&(c->尾数>=0.1&&c->尾数<1.0)){
状态=1;
}否则{
printf(“您没有在正确的范围内输入尾数\n”);
状态=0;
}
返回(状态);
}
sci not sum(sci not c1、sci not c2){
返回c1+c2;
}
sci_not_t产品(sci_not_t c1、sci_not_t c2){
返回c1*c2;
}

这里有很多错误。首先,您的参数对于
scan\u sci
是错误的。您没有传递指向您声明的结构的指针,而是传递了一个字符数组。您的声明应如下所示:

scinot_t scan_sci( scinot_t *collection );
为了符合向结构传递指针的要求,您需要将声明更改为以下内容。注意,返回指向堆栈上声明的变量的指针是非常糟糕的做法,并且容易出错,因此我们在
扫描sci
中对结构进行变异

void scan_sci( scinot_t *collection );

现在,在调用函数并使用
&
运算符传递其内存地址之前,您需要创建结构。

您有一些问题,这应该可以解决。首先,
扫描sci
现在使用指针返回值,成功时返回0,失败时返回非0(无法捕获所有故障模式)。除此之外,
scanf
是贪婪的,
e
是浮点字符串表示的合法部分,因此,您的原始版本仅解析1个参数,而double正在吃掉整个输入字符串,例如“123e123”为了解决这个问题,在
e
上进行拆分的基础上,将解析拆分为两个单独的解析

#include <stdio.h>
#include <stdlib.h>
#include <string.h>

typedef struct {
    double mantissa;
    int exp;
}scinot_t;

int scan_sci(scinot_t * tl){
    char buf[80]; 
    fgets(buf, 80, stdin);
    char * e = strchr(buf, 'e');
    if (!e) { return -1; }
    // Split buf up to act like 2 strings
    // e.g. 123.01e321 becomes:
    // 123.01 and 321 with e pointing to 321
    *e = '\0';
    e++;
    // Not checking any errors
    tl->mantissa = strtod(buf, NULL);
    tl->exp = strtol(e, NULL, 10);
    return 0;
}

int main(void){
    printf("Enter a value\n");
    // Init to 0 
    scinot_t sav = {0};
    int ret = scan_sci(&sav);
    if (ret) {
        printf("error, 'e' expected\n");
    }
    else {
        printf("%lfe%d", sav.mantissa, sav.exp);
    }

    return 0;
}
#包括
#包括
#包括
类型定义结构{
双尾数;
国际贸易;
}科学与技术;
内部扫描sci(scinot*tl){
char-buf[80];
fgets(buf,80,标准DIN);
char*e=strchr(buf,'e');
如果(!e){return-1;}
//将buf拆分为两个字符串
//例如,123.01e321变为:
//123.01和321,e指向321
*e='\0';
e++;
//不检查任何错误
tl->尾数=strtod(buf,NULL);
tl->exp=strtol(e,NULL,10);
返回0;
}
内部主(空){
printf(“输入值”);
//初始化为0
scinot_t sav={0};
int ret=扫描sci和sav;
如果(ret){
printf(“错误,'e'应为\n”);
}
否则{
printf(“%lfe%d”,sav.尾数,sav.exp);
}
返回0;
}

以下是一些从控制台读取的代码,并将值放入
scinot\t
没有任何验证

它使用scanf将整个字符串分为两部分。第一部分
%[^e]
读取任何不是“e”的
字符。然后读取“e”,最后读取指数

尾数首先作为字符串读取,然后使用sscanf重新解析

#include <stdlib.h>

typedef struct {
    double mantissa;
    int exp;
}scinot_t;

void scan_sci(scinot_t* s);

int main(void){
  scinot_t d;

  printf("Enter a value: ");
  scan_sci(&d);

  printf("Mantissa is %lf Exponent is %d\n", d.mantissa, d.exp);
  return 0;
}

void scan_sci (scinot_t *sn){
  char inp1[20];
  scanf("%[^e]e%d", inp1, &sn->exp);
  sscanf(inp1, "%lf", &sn->mantissa);
  return;
}
#包括
类型定义结构{
双尾数;
国际贸易;
}科学与技术;
无效扫描sci(scinot*s);
内部主(空){
科学及技术发展局;
printf(“输入值:”);
扫描(sci&d);
printf(“尾数是%lf,指数是%d\n”,d.尾数,d.exp);
返回0;
}
无效扫描sci(scinot*sn){
char-inp1[20];
scanf(“%[^e]e%d”,inp1,&sn->exp);
sscanf(inp1、%lf、&sn->尾数);
返回;
}
要测试尾数范围更新main,请执行以下操作:

int main(void){
  scinot_t d;

  printf("Enter a value: ");
  for (;;) {
    scan_sci(&d);
    if (d.mantissa>=0.1 && d.mantissa<=1.0)
      break;
    printf("You did not enter the mantissa in the correct range\nEnter a value: ");
  }

  printf("Mantissa is %lf Exponent is %d\n", d.mantissa, d.exp);
  return 0;
}
int main(无效){
科学及技术发展局;
printf(“输入值:”);
对于(;;){
扫描(sci&d);

如果(d.尾数>=0.1&&d.尾数代码中的一个问题是:

printf("%lfe%d", inp1);
这不能可靠地工作(尽管有可能工作);您需要分别通过
inp1
的两个元素:

printf("%lfe%d\n", inp1.mantissa, inp1.exponent);
另一个问题是扫描功能:

void scan_sci(scinot_t *value)
{
    *value= scanf("%lfe%d", &value->mantissa, &value->exp);
}
这完全是错误的,因为它试图将整数值(从
scanf()
返回的值)分配给结构。我认为您应该使用更类似于:

int scan_sci(scinot_t *value)
{
    if (scanf("%lfe%d", &value->mantissa, &value->exp) != 2)
        return EOF;
    return 0;
}
返回值现在指示是成功(0)还是失败(EOF)。您仍然存在这样一个问题,
%lf
将使用
%lf
转换规范愉快地阅读
0.25000e4
,使
e
%d
不匹配。使用
scanf()解决此问题的方法并不简单
,除非您要求值以
0开头。

但问题在于,第一个
%d
会将数字的前导零去掉(因此
0.0025e4
会被误解),因此您仍然会遇到问题。您最好扫描一串数字:

int scan_sci(scinot_t *value)
{
    char digits[1024];
    if (scanf("0.%1023[0-9]e%d", digits, &value->exp) != 2)
        return EOF;
    value->mantissa = ...calculation using the digits string...
    return 0;
}

您可以决定1024是否太大,并相应地调整数字。

1)您需要类型为
scinot\t的变量。
2)为什么要传递
value
/
inp1
?因为我的函数scan\u sci假定从输入源获取字符串如果在
scanf
中使用
%lf
,则
scanf
将整个浮点值读入双精度incl
int scan_sci(scinot_t *value)
{
    char digits[1024];
    if (scanf("0.%1023[0-9]e%d", digits, &value->exp) != 2)
        return EOF;
    value->mantissa = ...calculation using the digits string...
    return 0;
}