【发布时间】:2018-05-01 07:27:34
【问题描述】:
我编写了一个程序来创建横向滚动选取框效果,它可以在我的 Mac 终端上完美运行。但是,当我在我的树莓派(Raspbian Linux)上运行它时,效果会变得混乱并开始在新行上打印并且不会滚动整个文本长度。谁能弄清楚问题是什么?我已经尝试了好几天了。
// Compile: gcc marquee.c -o marquee -lncurses
// Usage: ./marquee filename length row col speed
// Reads text from a file and displays 'length' number of chars
// scrolling sideways at a given 'row, col' position at some indicated 'speed'
#include <curses.h>
#include <string.h>
#include <unistd.h>
#include <stdio.h>
#include <stdlib.h>
#include <fcntl.h>
#define ROW 10
int main(int ac, char *av[])
{
if(ac != 6){
printf("marquee [fileName] [row] [col] [speed (1-99)]\n");
perror("Insuffecient argument count\n");
exit(1);
}
char message[256];
int text_length;
int i;
int k;
int orgPos = atoi(av[4]);
int pos;
int row = atoi(av[3]);
int dir = 1;
int maxPos = atoi(av[2]);
int speed = atoi(av[5]);
int filedesc = open(av[1], O_RDONLY);
if(filedesc < 0) {
perror("Could not open file");
exit(1);
}
if(speed < 10)
speed = 500000;
if(speed >= 10 && speed < 20)
speed = 250000;
if(speed >= 20 && speed < 30)
speed = 120000;
if(speed >= 30 && speed < 40)
speed = 100000;
if(speed >= 40 && speed < 60)
speed = 80000;
if(speed >= 60 && speed < 70)
speed = 60000;
if(speed >= 70 && speed < 80)
speed = 40000;
if(speed >= 80 && speed < 90)
speed = 20000;
if(speed >= 90 && speed < 95)
speed = 10000;
if(speed >= 95 && speed <= 99)
speed = 5000;
int bytesRead = 0;
while(bytesRead == read(filedesc, message, 256) > 0){
}
// Get text length
text_length = strlen(message);
initscr(); // initialize curses
clear();
curs_set(0);
while(1) {
clear(); // clear last drawn iteration
pos = orgPos;
char * scroll;
scroll = malloc(2*maxPos);
for(i = 0; i<2*maxPos; i++)
{
scroll[i] = message[i%text_length];
}
for(i = 0; i < 1000; i++){
mvaddnstr(row, orgPos, &scroll[i%maxPos], maxPos);
usleep(speed);
refresh();
}
}
endwin();
if(close(filedesc) == -1)
{
perror("Error closing file");
exit(1);
}
}
这里肯定有很多改进,但请让您的调试目标弄清楚为什么它不能在 linux 上正确运行。这是一个示例测试用例:
$ ./marquee scroll.txt 25 0 0 50
scroll.txt 包含以下内容:
Hello, this is a test for the scrolling marquee.
【问题讨论】:
-
错误的编译命令:应该使用
gcc -Wall -Wextra -g marquee.c -o marquee -lncurses然后use thegdbdebugger。成为scared 的undefined behavior -
另外,Stack Overflow 不是 fix-my-bugs 服务,所以你的问题是题外话。
-
我的意思是更多地提出这个问题,“为什么它在两个操作系统之间的行为不同?”因为一个工作正常,另一个不行;与其说是“修复我的错误”。
-
文件不起作用(即使在您的笔记本电脑上),您仍然有未定义的行为。
-
我在 Solaris 11.4 上运行了您的程序(唯一需要的更改是包含
<ncurses.h>而不是<curses.h>)。它对我来说运行得很好,没有你提到的终端窗口损坏发生在 linux 上。当谈到终端输出差异时,我的第一步是检查终端类型。在 Solaris 上,我的默认术语类型是xterm-256color。在我运行 10.13.4 的 Mac 上,它是xterm。然后我尝试了几种不同的术语类型:TERM=ansi TERM=xterm TERM=xterms TERM=at386 TERM=dtterm,它们都显示了未损坏的滚动输出。
标签: c linux macos unix ncurses