Самая очевидная проблема, которая может привести к ошибке сегментации, заключается в следующем коде:
if(argc!=2)
{
puts("Invalid number of arguments: Usage:headband <String>");
}
char *headtext = argv[1];
После определения того, что было предоставлено недопустимое количество аргументов, вы приступаете к назначению указателя наargv[1]
.Если пользователь не предоставил ваш аргумент, результат передает NULL
в strlen()
.Это приводит к неопределенному поведению, и strlen(NULL)
обычно вылетает в Linux \ Unix.В моем кратком тестировании предоставление аргумента привело к прокрутке оголовья без какого-либо сбоя.
Возможно, вы захотите изменить свой код на что-то похожее на следующее:
if(argc<2)
{
puts("Invalid number of arguments: Usage:headband <String>");
exit(EXIT_FAILURE);
}
char *headtext = argv[1];
Обновление
Кажется, ваш текущий код излишне сложен (например, вложенные бесконечные циклы) для того, что, как я считаю, является его предназначением.Есть также несколько проблем с кодом в его текущей форме, которые следует устранить.* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * Утечка памяти , возникающая в результате вызова malloc()
в функции substr()
и последующего потери указателя на выделенную память.Если предоставленный пользователем текст превышает размер буфера temp[100]
, вы переполните буфер в функции append()
.Также нет необходимости вычислять длину headtext
более одного раза, поскольку ее длина не изменится.
Я утверждаю, что curses следует использовать над необработанными кодами выхода терминала .Библиотека curses фактически является оболочкой для необработанных кодов терминала и предоставляет гибкий и эффективный API, так что прикладным программам не нужно беспокоиться о базовых возможностях терминала.Возможно, NCURSES Programming HOWTO или X / Open Curses, Справочные страницы могут быть полезны.
IЯ не являюсь экспертом curses , однако в следующем примере показан другой подход на основе curses, который слабо основан на исходном коде и, по-видимому, имеет тот же результат *:
#include<curses.h>
#include<signal.h>
#include<stdlib.h>
#include<string.h>
#include<unistd.h>
/* maximum x and y co-ordinates of the window */
int max_x, max_y;
/* pointer to headband buffer */
char * headband = NULL;
/* counter for streaming and scolling headband text */
unsigned int count;
/* Handler for window resize */
void handle_winch(int sig)
{
/* Function for initializing curses & headband buffer */
void my_init();
/* Disable signal handler during reinitialization */
signal(SIGWINCH, SIG_IGN);
/* Reinitialize the window to update data structures */
endwin();
my_init();
}
/* Function for initializing curses & headband buffer */
void my_init()
{
/* Initialize / Reinitialize screen for ncurses */
initscr();
curs_set(0);
clear();
refresh();
getmaxyx(stdscr, max_y, max_x);
/* Allocate / Reallocate and initialize scrolling headband buffer */
free(headband);
headband = (char *)malloc(max_x+1);
memset(headband, ' ', max_x);
headband[max_x] = '\0';
count = 0;
/* Setup signal handler for window resizing */
signal(SIGWINCH, handle_winch);
}
/* Implements a scrolling headband that takes a
* string argument and scrolls continously */
int main(int argc, char* argv[])
{
char * headtext;
int headtext_len;
int size;
if(argc<2)
{
puts("Invalid number of arguments: Usage:headband <String>");
exit(EXIT_FAILURE);
}
/* Get headtext from the argument argv[1] and compute length */
headtext = argv[1];
headtext_len = strlen(headtext);
/* Call common initialization / reinitialization routine */
my_init();
/* Run this loop continuously to keep scrolling */
for(;;)
{
/* Store & use copy of max_x in case original max_x is
* modified in signal handler by window resize event */
size = max_x;
/* Rotate headband by shifting entire buffer and then
* appending next character from headtext buffer */
memmove(&headband[0], &headband[1], size-1);
headband[size-1] = headtext[count++ % headtext_len];
/* Update window */
move(0,0);
mvaddstr(0,0,headband);
refresh();
usleep(50000);
}
/* Unreachable, but included for completeness */
endwin();
free(headband);
exit(EXIT_SUCCESS);
}
* Включает обработку изменения размера окна