Как я могу отладить мою рекурсивную функцию, которая вызывает ошибку переполнения стека? - PullRequest
3 голосов
/ 20 апреля 2020

Проблема, которую я пытаюсь решить - упражнение KR2 1-22; 'написать программу, чтобы "сложить" длинные строки ввода в две или более короткие строки после последнего непустого символа, который находится перед n-м столбцом ввода. Убедитесь, что ваша программа делает что-то умное с очень длинными строками, и если перед указанным столбцом нет пробелов или табуляций '.

Я пытался сделать с рекурсивной функцией, которая просто застревает.

Пример ошибочного поведения:
Привет, мир << вход <br>вывод >>
ад
o wo
o wo
o wo
o wo
. ...
...
Ожидаемое поведение:
привет мир << input <br>output >>
hell
o wo
rld

Второй пример ошибочного поведения:
он лло мир << ввод <br>вывод >>
он
лло
лло лло
лло лло
лло
....
...
Среднее ожидаемое поведение:
he llo world << input <br>output >>
he
llo
wor
ld

См. Код ниже:

#include <stdio.h>
#define PAGEWIDTH 5
#define MAXLINE 1000

int getline(char line[], int maxline);
void fold(char line[], int start);

/* "fold" long input lines into two or more shorter lines after
  the last non-blnk character that occurs before the n-th
  column of input */
int main()
{
    int len;                /* current line length*/
    char line[MAXLINE];     /* current input lne*/

    while ((len = getline(line, MAXLINE)) > 0)
        if (len > PAGEWIDTH)
            fold(line, 0);
    return 0;
}

/* getline : read a line into s, return length */
int getline(char s[], int lim)
{
    int c, i;

    c = 0;
    for (i = 0; i < lim - 1 && (c = getchar()) != EOF && c != '\n'; ++i)
        s[i] = c;
    if (c == '\n') {
        s[i] = c;
        ++i;
    }
    s[i] = '\0';

    return i;
}

void fold(char line[], int start)
{
    int i, lstnb;
    i = lstnb = 0;

    for (i = 0; i < PAGEWIDTH-1 && line[start + i] != '\0'; ++i) {
        if (line[start + i] != ' ')
            lstnb = i;
    }
    for (i = 0; i <= lstnb; ++i)
        putchar(line[start + i]);

    putchar('\n');
    if(line[lstnb + 1] != '\0')
        fold(line, lstnb + 1);
}

1 Ответ

2 голосов
/ 20 апреля 2020

хороший вопрос. Во-первых, я думаю, что рекурсивное решение здесь не идеально. Я понял, что он работает для входных данных, которые вы дали, но, учитывая, как мало PAGEWIDTH, вы, скорее всего, столкнетесь с проблемами при больших входах. Использование al oop сделает вашу жизнь проще и приведет к более надежной функции.

Тем не менее, ваша проблема заключается в рекурсивном вызове, который вы делаете в функции fold(), вы предоставляете неверный стартовый индекс. Это означает, что вы не двигаетесь вперед в линии с каждым вызовом. Кроме того, вы не можете четко определить базовый вариант (т. Е. Когда закончить рекурсию). Вы можете сделать это, изменив условия для l oop или передав длину строки (n) в функцию и проверив, является ли start> n.

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

Я не уверен, что вы ищете с точки зрения ответа, но если эти предложения не подходите ближе, я вставил исправление в пастин здесь . Я не размещал это здесь, если вы хотите решить это самостоятельно.

Надеюсь, это сработает, дайте мне знать, если я что-то пропустил.

...