LINUX.ORG.RU

Codeblocks, ncurses и gdb

 ,


0

1

Есть простейший прогрессбар на ncurses

#include <ncurses.h>
#include <cstring>

void showProgress(unsigned short percent);

int main(int argc, char **argv)
{
    initscr();
    for (int i = 0; i < 100; i++)
    {
        showProgress(i);
        getch();
    }

    endwin();
    return 0;
}

void showProgress(unsigned short percent)
{
    char *progressBar = new char [40];
    *progressBar = '\0';
    strcpy(progressBar, "[");
    int i;
    for (i = 0; i < percent / 5; i++)
    {
        strcat(progressBar, "|");
    }
    for (;i < 20; i++)
    {
        strcat(progressBar, " ");
    }
    strcat(progressBar, "]  ");
    char *tmpBuf = new char [10];
    sprintf(tmpBuf, "%i%%", (int)percent);
    strcat(progressBar, tmpBuf);
    move(2, 0);
    printw("%s\n", progressBar);
    refresh();
    delete [] tmpBuf;
    delete [] progressBar;
}

Debian 7.1, gcc и gdb из репов сида. Проблема в том, что при попытке отладки такой программы GDB завершается при попытке перехода на следующую строку. Если запустить Codeblocks из консоли то отладка работает. Ну просто уж не знаю что делать, с каждым днём всё радостнее жить. Надеюсь на вашу помощь.

★★★★

Последнее исправление: cetjs2 (всего исправлений: 1)

GDB завершается при попытке перехода на следующую строку.

Что значит завершается и на какой строке?

ziemin ★★
()
Ответ на: комментарий от ziemin

Кстати, зачем тебе оба strcat в циклах, если можно просто символ устанавливать в буфере.

Да и последний не нужен:

...
progressBar[i] = '|';
...
progressBar[i] = ' ';
...
progressBar[i] = '\0';
...
printw("[%s] %i%%\n", progressBar, (int)percent);

ziemin ★★
()
Последнее исправление: ziemin (всего исправлений: 2)

Среда при попытке сделать stop debug или rebuild случайно не говорит «Unable to stop the debug process»?

Cheater
()
Ответ на: комментарий от ziemin

Ну предположим я поставил breakpoint на initscr(). Нажимаю переход на следующую строку и отладка завершается как ни в чем не бывало. «Unable to stop the debug process» замечено тоже не было. Вот выхлоп нажатия переход на следующую строку

WRG ★★★★
() автор топика
Ответ на: комментарий от WRG

[Inferior 1 (process 8725) exited with code 01]

Значит внутри initscr() есть вызов exit(1).

Смотрим справку:

Upon successful completion, initscr() returns a pointer to stdscr. Otherwise, it does not return.

Вот и ответ.

ziemin ★★
()
Ответ на: комментарий от WRG

The initscr() function determines the terminal type and initialises all implementation data structures. The environment variable specifies the terminal type. The initscr() function also causes the first refresh operation to clear the screen. If errors occur, initscr() writes an appropriate error message to standard error and exits.

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

ziemin ★★
()

Есть простейший прогрессбар на ncurses

при попытке отладки такой программы GDB завершается при попытке

читайте же документация полностью. или google:howto debug ncurses application

ps. весь ваш showProgress укладывается в один printf :) а наколбашено-то, наколбашено..

MKuznetsov ★★★★★
()
Ответ на: комментарий от Cheater
mate-terminal --disable-factory -t $TITLE -x 
WRG ★★★★
() автор топика
Ответ на: комментарий от MKuznetsov

ну я пока что учусь :) уже укоротил, понял что квадратные скобки в progressBar совать необязательно)

WRG ★★★★
() автор топика
Ответ на: комментарий от beastie

На pure C твой код выглядел бы примерно так:

#include <ncurses.h>
#include <stdio.h>
#include <unistd.h>

char *
progress(unsigned int percent)
{
        static char pBar[40] = {};
        char *p = pBar;
        int i;

        if (percent > 100)
                percent = 100;

        *p++ = '[';

        for (i = 0; i < percent / 5; i++)
                *p++ = '|';

        for (; i < 20; i++)
                *p++ = ' ';

        *p++ = ']';

        snprintf(p, sizeof(pBar) - (p - pBar), "%4i%%", percent);

        return pBar;
}

int
main(int argc, char **argv)
{
        char *pBar;
        int i;

        initscr();

        for (i = 0; i <= 100; i++) {
                pBar = progress(i);
                mvprintw(2, 0, "%s\n", pBar);
                refresh();
                sleep(1);
        }

        endwin();

        return 0;
}
PS: правда там ещё куча места для оптимизации. И меленький бонус: gdb работает. =)

beastie ★★★★★
()
Последнее исправление: beastie (всего исправлений: 1)
Ответ на: комментарий от beastie

спасибо, но gdb всё же не работает)) симптомы те же. надо будет глянуть в .xsession-errors.

WRG ★★★★
() автор топика
Ответ на: комментарий от beastie

кстати, как всё же лучше оформлять код? раньше делил весь код на маленькие блоки, как в примере beastie. Потом мочему-то стал лепить всё в кучу, наверно потому, что больше кода на экране видно. Как всё таки торт? ИМХО с разделением легче читать.

WRG ★★★★
() автор топика
Ответ на: комментарий от WRG

Дело вкуса. Я придержуюсь KNF и разделение на «логические» блоки. Читать проще. Когда всё идёт сплошной простынёй глазу не за что зацепиться.

beastie ★★★★★
()
Ответ на: комментарий от WRG

Кстати, printf is your friend! ;)

har *
progress(unsigned int percent)
{
        static char pBar[40];
        char done[] = "||||||||||||||||||||";

        if (percent > 100)
                percent = 100;

        snprintf(pBar, sizeof(pBar), "[%-20.*s]%4i%%", percent / 5, done, percent);

        return pBar;
}

Это к вопросу об улучшениях. :)

beastie ★★★★★
()
Последнее исправление: beastie (всего исправлений: 2)
Ответ на: комментарий от beastie

Можно если не затруднит правильную С++ реализацию, чтобы понять разницу как следует и как должно быть?

WRG ★★★★
() автор топика
Ответ на: комментарий от Gvidon

Не надо писать «как удобно», надо писать понятно, эффективно и без ошибок. Это нифига не одно и то же

Синее и мягкое тоже не одно и то же. Но ничто не мешает синему быть мягким, а мягкому синим. У Вас, как я понимаю, эти вещи несовместимы.

anonymous
()
Вы не можете добавлять комментарии в эту тему. Тема перемещена в архив.