Передача вектора в функцию для вычисления длины в 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