K&R C- 431416个字符
高度尊重标准。使用ncurses,因此它在很大程度上应独立于终端。由于为保留字符串中的预期空白而进行了一些欺骗性操作,因此当文本碰到侧面时会有些口吃。
要使用的字符串应作为命令行的第一个参数传递(如果包含空格,则应将其转义,如果!
如我的测试字符串(Hello, World!
)那样包含,则应转义)。
#include <ncurses.h>
#include <unistd.h>
#define T usleep(1e5),S(l)
#define U mvprintw(23,0,"%s",l),refresh()
char l[63],*p,*q,r;
S(char*s){r=0;if(*s==32)q=s++;else{for(;*s-32||*(s+1)-32;s++);
for(q=s;*s==32;s++);(s-q)&1?s--:usleep(1e5);}
for(r=0;*s;*q++=*s++){*s-32?r=1:0;}return r;}
main(int c,char**v){initscr();curs_set(0);for(c=0;c<62;l[c++]=32);
for(p=*++v;*p;){l[52]=*p++;U;T;U;T;U;T;}for(;T;U);getch();endwin();}
以更具可读性和评论性的形式:
#include <ncurses.h>
#include <unistd.h>
char l[63] /* take advantage of 0 initialization */,
*p,*q, r;
/* Remove the first unwanted space. Unwanted means at the begining of
* the line, all of even length blocks between non-spaces, and
* all-bu-one of odd length blocks between non-spaces.
*
* Return true if the removed space occurs before a non-space character.
*/
S/*lide marquee*/(char*s){
r=0; /* initialize the return value */
if(*s==' '){
q=s++;
} else {
/* Find the start of first block of contiguous spaces */
for(;*s-' '||*(s+1)-' ';s++);
for(q=s;*s==' ';s++); /* q holds the start, s finds it's end */
/* if this block is even length remove all, if odd, all but one */
if( (s-q)%2 )s--; else usleep(1e5);
}
/* copy from s to q all the way to the end */
for(r=0;*s;*q++=*s++){
if(*s-' ')r=1; /* note if we pass a non-space */
}
return r;
}
main(int c,char**v){
initscr();curs_set(0); /* setup ncurses with invisible cursor */
for(c=0;c<62;l[c++]=' '); /* initialize l */
for(p=*++v;*p;){ /* load the message into the marque, skipping space */
l[52]=*p++;
mvprintw(23,0,"%s",l),
refresh();
usleep(1e5),
S(l);
usleep(1e5),
S(l);
usleep(1e5),
S(l);
}
for(;usleep(1e5),S(l);mvprintw(23,0,"%s",l),refresh()); /* keeping sliding until we're done. */
getch();
endwin();
}
xterm
,vt102
...?