Как правильно использовать va_list, добавить, начать, закончить? - PullRequest
0 голосов
/ 06 апреля 2019

Я работаю над созданием собственной функции printf. Я начинаю с более мелких функций, которые потребуются для завершения основного проекта.

Моя функция должна возвращать сумму аргументов, если i = 0, или она должна возвращать сумму размера последних строк символов nb, переданных в качестве параметра, если i = 1. Так что если у меня есть: ./a.out 0 2 3 3, он должен вернуть 6, например. Однако все, что я получаю, это 1, а если второй аргумент равен 3, то я получаю странное отрицательное число.

Может ли кто-нибудь помочь мне понять это или, по крайней мере, указать мне правильное направление? Заранее спасибо!

Я пытался использовать vprintf, но я не знаю, как правильно его использовать. Кстати, единственная причина, по которой я сейчас использую printf, - это тестирование. Я сделаю модульные тесты после того, как я закончу.

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

int my_getnbr(char const *str);

int sum_stdarg(int i, int nb, ... )
{
    int j = 0;
    int signal = 0;
    va_list(args);

    va_start(args, nb);
    while (nb > j) {
        if(i == 0) {
        signal = signal + va_arg(args, int);
    }
        else if (i == 1) {
        signal = signal + strlen(va_arg(args, char*));
    }
    j++;
    }
    va_end(args);
    return (signal);
}

int my_getnbr(char const *str)
{
    int i = 0;
    long cpy = 0;
    int intcpy;

    while ((str[i] < '0' || str[i] > '9') && str[i] != '\0')
        i++;
    if (str[i - 1] == '-') {
        while ((str[i] >= '0' && str[i] <= '9') && str[i] != '\0') {
            cpy = cpy * 10 - (str[i] - 48);
            i++;
        }
    } else {
        while ((str[i] >= '0' && str[i] <= '9') && str[i] != '\0') {
            cpy = cpy * 10 + (str[i] - 48);
            i++;
        }
    }
    if (cpy < -2147483648 || cpy > 2147483647)
        return (0);
    intcpy = cpy;
    return (intcpy);
}

int main(int ac, char **av)
{
    printf("%d\n", sum_stdarg(my_getnbr(av[1]), my_getnbr(av[2])));
    return (0);
}

1 Ответ

1 голос
/ 07 апреля 2019
va_list(args);

va_list - это тип, а не функция. Вы должны объявить переменную типа va_list и использовать ее с другими вещами va_ *.

Далее:

int sum_stdarg(int i, int nb,  ... )  // '...' declared as third parameter
[...]
printf("%d\n", sum_stdarg( my_getnbr(av[1]),   my_getnbr(av[2])));  // 'sum_stdarg' called with 2 arguments

Вы фактически не указали ни один из аргументов, к которым va_start должен получить доступ. Вызов здесь va_start вызовет неопределенное поведение.

Если ваш второй аргумент равен 3, то при вызове sum_stdarg не запускается ни if в цикле while, поэтому ваша возвращаемая переменная никогда не назначается и по-прежнему содержит неинициализированную память при возврате.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...