Предаване на вектор към функция за изчисляване на дължина в C

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

struct vector
    {
        double x;
        double y;
        double z;
    };

    struct vector *array;
    double length(struct vector*);
int main()
{
    int num,i;
    double xin;
    double yin;
    double zin;
    char buffer[30];
    char buffer2[30];

    printf("Enter number of vectors:");
    fgets(buffer, 30, stdin);
    sscanf(buffer, "%d", &num);


    array = malloc( sizeof(struct vector) * num);

           for(i=0;i<=num;i++)
           {
               printf("Please enter x y z for the vector:");
               fgets(buffer2,100,stdin);
               sscanf(buffer2, " %lf %lf %lf", &xin, &yin, &zin);

                   array[i].x = xin;
                   array[i].y = yin;
                   array[i].z = zin;
           }

           for(i=0;i<=num;i++)
           {

               printf( "Vector:%lf %lf %lf has a length of %lf\n", array[i].x, array[i].y, array[i].z, length(&array[i]));

           }
}


double length(struct vector* vec)
{

 return sqrt( (vec->x * vec->x) + (vec->y * vec->y) + (vec->z * vec->z) );

}

Добре, горният код е почти завършен, той пита потребителя за броя на векторите, след което пита потребителя за стойностите на тези вектори, след което ще изчисли дължината и ще я отпечата съответно.

Опитвам се да направя някаква проверка за грешки тук, но не мога да го разбера... Потърсих всяка възможна върната стойност за fgets и sscanf, просто не мога да го разбера

Защитни функции

ПЪРВО printf-------въведеното трябва да бъде само едно число, по-голямо от 0 и EOF трябва да върне съобщение като printf("въведете число--чао!"), затова опитах

while( sscanf(buffer, "%d", &num) ==1 && num > 0 )

но все още работи, ако се въведе нещо като 3dadswerudsad

също така, когато потребителят въвежда 3-те стойности за вектора, ако изобщо нещо различно от 3 двойни са въведени за вектор, програмата трябва да прекрати със съобщение, така че опитах

while( sscanf(buffer2, "%lf %lf %lf", &xin, &yin, &zin) ==3 )

но не проверява за тези неправилни входове!!

побърквам се


person Superman    schedule 09.01.2015    source източник
comment
вижте отговора ми на предишния ви въпрос (мисля, че този въпрос трябваше да е редакция на предишния въпрос.)   -  person user3629249    schedule 09.01.2015


Отговори (2)


Почти сте прав, трябва да наименувате формалността и функцията и да я използвате по подходящ начин:

double veclength (struct vector v) {
   return sqrt( (v.x * v.x) + (v.y * v.y) + (v.z * v.z) );
}

за ефективност и други причини може да помислите за предаване на указател (към постоянен вектор, тъй като не го променяте)

double veclengthptr (const struct vector* v) {
   return sqrt( (v->x * v->x) + (v->y * v->y) + (v->z * v->z) );
}

и тогава можете по-късно да използвате veclength(array[i]) или veclengthptr(array+i) (същото като veclengthptr(&a[i]))

Трябва да искате да дадете прототипи (може би в някакъв заглавен файл), преди да използвате тези функции:

 double veclength (struct vector);
 double veclengthptr (const struct vector*);

Забележете, че от съображения за ефективност може да искате да декларирате тези прототипи като static inline (и да дадете имплементацията им в същата единица за превод), така че да поискате вградени функции:

 static inline double veclength (struct vector);

Вземете навика да компилирате с всички предупреждения и информация за отстраняване на грешки, напр. gcc -Wall -Wextra -g

По отношение на използването на sscanf(3) като sscanf(buf, "%d", &num) забележете, че ако buf съдържа 3dxde той успява чрез четене на 3 в numdxde неанализиран). Може да искате да използвате %n в sscanf (прочетете документацията му!) или да използвате strtol (3)

person Basile Starynkevitch    schedule 09.01.2015
comment
може да има смисъл да декларирате версията на указателя като double veclengthptr (const struct vector* v), тъй като не прави модификации на своята цел - person Jasen; 09.01.2015
comment
Моите C-умения може да са станали малко ръждясали, но не можахте ли просто да декларирате veclength като double veclength (const struct vector &v) и да забравите за тази функция, която се нуждае от указател? Или това беше едно от нещата, които работят само в C++? - person mmgross; 09.01.2015
comment
Не, формалностите (const struct vector&v) са валидни в C++, но не и в C. C няма препратки. - person Basile Starynkevitch; 09.01.2015
comment
трябва ли моят прототип да се промени, ако направя veclengthptr?? - person Superman; 09.01.2015
comment
Ха-ха, всичко е на върха, но го накарах... БЛАГОДАРЯ, сериозно ми помогна - person Superman; 09.01.2015
comment
също трябваше да използвам превключвателя -lm с моя компилитор gcc...продължаваше да ми дава недефинирана препратка към sqrt() - person Superman; 09.01.2015
comment
гласуван против, защото този отговор няма нищо общо с въпроса как да проверявате за невалидни входове - person user3629249; 09.01.2015

Функцията може да се реализира по следния начин.

double length(struct vector vec)
{
    return sqrt( vec.x*vec.x + vec.y*vec.y + vec.z*vec.z );
}
person Codor    schedule 09.01.2015
comment
гласуван против, защото този отговор няма нищо общо с въпроса как да проверявате за невалидни входове - person user3629249; 09.01.2015