Проверка процедуры в порядке, но при вызове из меню выдает неинициализированные ошибки. С - PullRequest
0 голосов
/ 26 декабря 2010

Язык португальский, но я думаю, вы поняли. Мои главные вызовы только функция меню (функция в комментарии это тест, который работает).

В меню я ввожу опцию 1, которая вызывает ту же функцию. Но что-то не так.

Если я проверю это только на входе:

(1/1) х ^ 2 // читает полиномиал (2/1) // читает рациональное и возвращает 4

(вы можете догадаться, что он делает, вычисляет значение набора x над рациональным)

Мои полиномы - это линейные связанные списки с коэффициентом (рациональным) и степенью (int)

int main ()
{
    menu_interactivo ();
//  instanciacao ();
    return 0;
}

void    menu_interactivo(void)
{
    int i;
    do{
        printf("1. Instanciacao de um polinomio com um escalar\n");
        printf("2. Multiplicacao de um polinomio por um escalar\n");
        printf("3. Soma de dois polinomios\n");
        printf("4. Multiplicacao de dois polinomios\n");
        printf("5. Divisao de dois polinomios\n");
        printf("0. Sair\n");
        scanf ("%d", &i);
        switch  (i)
        {
            case 0: exit(0);
                    break;
            case 1: instanciacao ();
                    break;
            case 2: multiplicacao_esc ();
                    break;
            case 3: somar_pol ();
                    break;
            case 4: multiplicacao_pol ();
                    break;
            case 5: divisao_pol ();
                    break;
            default:printf("O numero introduzido nao e valido!\n");
        }
    }
    while (i != 0);
}

Когда я вызываю его с помощью меню с тем же вводом, оно не прекращает чтение полиномиала (я знаю это, потому что оно не запрашивает у меня рациональное, как в другом примере)

Я запустил его с помощью valgrind --track-originins = yes, возвращая следующее:

==17482== Memcheck, a memory error detector
==17482== Copyright (C) 2002-2009, and GNU GPL'd, by Julian Seward et al.
==17482== Using Valgrind-3.5.0 and LibVEX; rerun with -h for copyright info
==17482== Command: ./teste
==17482== 
1. Instanciacao de um polinomio com um escalar
2. Multiplicacao de um polinomio por um escalar
3. Soma de dois polinomios
4. Multiplicacao de dois polinomios
5. Divisao de dois polinomios
0. Sair
1
Introduza um polinomio na forma (n0/d0)x^e0 + (n1/d1)x^e1 + ... + (nk/dk)^ek,
com ei > e(i+1):
(1/1)x^2
==17482== Conditional jump or move depends on uninitialised value(s)
==17482==    at 0x401126: simplifica_f (fraccoes.c:53)
==17482==    by 0x4010CB: le_f (fraccoes.c:30)
==17482==    by 0x400CDA: le_pol (polinomios.c:156)
==17482==    by 0x400817: instanciacao (t4.c:14)
==17482==    by 0x40098C: menu_interactivo (t4.c:68)
==17482==    by 0x4009BF: main (t4.c:86)
==17482==  Uninitialised value was created by a stack allocation
==17482==    at 0x401048: le_f (fraccoes.c:19)
==17482== 
==17482== Conditional jump or move depends on uninitialised value(s)
==17482==    at 0x400D03: le_pol (polinomios.c:163)
==17482==    by 0x400817: instanciacao (t4.c:14)
==17482==    by 0x40098C: menu_interactivo (t4.c:68)
==17482==    by 0x4009BF: main (t4.c:86)
==17482==  Uninitialised value was created by a stack allocation
==17482==    at 0x401048: le_f (fraccoes.c:19)
==17482== 

Теперь я дам вам функции, которые называются

.
void    le_pol (pol *p)
{
    fraccao f;
    int     e;
    char    c;

    printf ("Introduza um polinomio na forma (n0/d0)x^e0 + (n1/d1)x^e1 + ... + (nk/dk)^ek,\n");
    printf("com ei > e(i+1):\n");

    *p = NULL;

    do
    {
        le_f (&f);

        getchar();
        getchar();

        scanf ("%d", &e);

        if (f.n != 0) //polinomios.c line 163
            *p = add (*p, f, e);

        c = getchar ();

        if (c != '\n')
        {
                getchar();
                getchar();
        }
    }
    while (c != '\n');
}


void    instanciacao (void)
{
    pol     p1;
    fraccao f;

    le_pol (&p1);
    printf ("Insira uma fraccao na forma (n/d):\n");
    le_f (&f);
    escreve_f(inst_esc_pol(p1, f));
}


void    le_f (fraccao *f)
{ //line fraccoes.c line 19
    int n, d;

    getchar ();
    scanf ("%d", &n);
    getchar ();
    scanf ("%d", &d);
    getchar ();

    assert (d != 0);

    *f = simplifica_f(cria_f(n, d));
}

simpifica_f упрощает рациональное, а cria_f создает рациональное отношение с учетом числителя и знаменателя

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

Если вы хотите, чтобы я дал несколько тестов, просто опубликуйте его.

Увидимся.

Ответы [ 2 ]

2 голосов
/ 27 декабря 2010

Возможно, вам необходимо ввести некоторую проверку ошибок - в частности, вы должны проверить, что вызовы scanf() действительно преобразовывают значение. Я подозреваю, что разбросанные getchar() звонки потребляют слишком мало или слишком много, и что одна или несколько ваших scanf() операций не выполняются, оставляя такие переменные, как n и / или dle_f() ) неинициализирован, что затем вызывает проблемы в дальнейшем.

Всегда, но всегда, предполагайте, что ввод / вывод (особенно ввод) будет неправильным - на другом конце (например, я или вы) будет идиот, печатающий данные иначе, чем ожидает ваш код.

В целях отладки, по крайней мере, замените вызовы getchar() своей собственной функцией, которая читает символ и отображает прочитанное (и обнаруживает EOF и выдает ошибку при возникновении ошибки - пока у вас не будет более сложной схемы обработки ошибок) на месте):

#include <ctype.h>
#include <stdio.h>

static void readchar(void)
{
    int c;
    if ((c = getchar()) == EOF)
    {
        fprintf(stderr, "Unexpected EOF - exiting\n");
        exit(1);
    }
    printf("Got: %d (0x%02X) %c\n", c, c, isprint(c) ? c : '?');
}

Аналогично, вы должны сделать нечто подобное с scanf() вызовами:

static void readint(int *var)
{
    if (scanf("%d", var) != 1)
    {
        fprintf(stderr, "Failed to read integer - exiting\n");
        exit(1);
    }
    printf("Got: %d\n", *var);
}

Используйте это вместо ваших scanf() звонков. Вы можете улучшить диагностику с readint(), прочитав оставшуюся часть строки в буфер и напечатав следующее:

static void readint(int *var)
{
    if (scanf("%d", var) != 1)
    {
        char buffer[32];
        fprintf(stderr, "Failed to read integer - exiting\n");
        if (fgets(buffer, sizeof(buffer), stdin) != 0)
             fprintf(stderr, "Residual data: <<%s>>\n", buffer);
        exit(1);
    }
    printf("Got: %d\n", *var);
}

Вы можете получить две новые строки из печати «остаточных данных», но это лучше, чем ничего (что может произойти, если остаточная строка длиннее 31 символа. Информации, вероятно, достаточно, чтобы сказать вам, где проблема - не хватает лучше отслеживание ввода.

Использование scanf() обычно не лучший способ - вы получаете лучший контроль над обработкой ошибок и т. Д., Если вы читаете строки с помощью fgets(), а затем сканируете ввод с помощью sscanf().

0 голосов
/ 29 декабря 2010

Просто вставьте

getchar()

После чтения int из меню, и все готововыбор меню.Используйте этот призыв, чтобы отменить его, и все идет по плану.

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