방금 상자 문자를 사용하여 정보를 표시하는 C++] 프로그램을 작성했습니다. 터미널 앱을 사용하여 macOS에서 프로그램을 실행했는데 제대로 작동했습니다.
내가 전환 할 때데비안 리눅스동일한 코드를 사용하고 다시 컴파일했더니 이 문제가 발생했습니다! 온라인에서 답변을 검색했지만 이 질문과 관련된 답변을 찾지 못했습니다. 나는 이것을 두 가지 모두로 테스트했습니다LX 터미널그리고 URXVT.
다음은 이 문제에 대해 재현 가능한 최소한의 예입니다.
#include <ncurses.h>
#include <iostream>
int ch;
int main() {
setlocale(LC_CTYPE, "");
initscr();
noecho();
keypad(stdscr, true);
nodelay(stdscr, true);
curs_set(0);
start_color();
use_default_colors();
init_pair(1, COLOR_BLUE, -1);
clear();
refresh();
while ((ch = getch()) != 'q' && ch != 'Q') {
attrset(COLOR_PAIR(1));
mvprintw(0,0,"┏━┓");
mvprintw(1,0,"┗━┛");
}
refresh();
endwin();
return 0;
}
다음 명령을 사용하여 이 데모를 컴파일합니다.
g++ -g -c -o main.o test.cpp && g++ -g -o test main.o -std=c++11 -Wall -pedantic -lncurses
또는
LDLIBS=-lncurses make test
보여주는 대신
┏━┓
┗━┛
다음과 같이 표시됩니다.
M-b~T~OM-b~T~AM-b~T~S
M-b~T~WM-b~T~AM-b~T~[
실제 화면 이미지
macOS의 일반(필수) 표시:
Linux에서는 예외가 표시됩니다.
답변1
문제는 별도의 기호를 사용하는 대신 리터럴 문자 ┌
, ─
, ┐
, └
, ─
를 사용하고 있다는 것입니다 . ( pper/ ower 및 eft/ ight) 및 기호 이름을 사용해야 하며 터미널에서 이러한 이름을 나타내는 방법을 알아봅시다.┘
ncurses
ACS_??CORNER
U
L
L
R
ACS_HLINE
ncurses
여기에서 코드를 수정하세요.
mvprintw(0,0,"┏━┓");
mvprintw(1,0,"┗━┛");
이와 관련하여,
move(0,0); addch(ACS_ULCORNER); addch(ACS_HLINE); addch(ACS_URCORNER);
move(1,0); addch(ACS_LLCORNER); addch(ACS_HLINE); addch(ACS_LRCORNER);
코드는 이식 가능하게 작동해야 합니다. 또한 프로그램 종료 시 터미널이 제대로 재설정되도록 main()
프로그램의 끝을 단순에서 다음과 같이 변경했습니다 .return 0
endwin();
exit(0);
컴파일 test.cpp
하고 실행하고,
LDLIBS=-lncurses make test && ./test
특별한 순서 없이 유용한 참고 자료:
답변2
MacOS에서 -lncurses
와이드 문자 구성을 위한 ncurses에 대한 링크는 일반적으로 로 제공됩니다 -lncursesw
. setlocale
호출은 다른 결과(일반 문자 대 와이드 문자)를 제공했으며 상자 문자 리터럴 문자열(UTF-8)에 대한 결과도 달랐습니다.
추가 자료:
- Curses 라이브러리는 OS X High Sierra에서 와이드 문자를 지원하지 않습니다., 내 설명을 위해
- 대체 구성ncurses 매뉴얼에서
- 키 이름, 이는 다음으로 확장됩니다.컨트롤 삭제그리고다음에 추가, 눈치 챘다
- 128보다 큰 값은 다음과 같은 메타 문자입니다(화면이 초기화되지 않았거나 메타(3x)가 TRUE 인수로 호출된 경우).MX기호 또는 그 자체로 나타납니다. 후자의 경우 값이 인쇄되지 않을 수 있습니다. 이는 X/Open 사양을 따릅니다.
근본적인 문제는 상자 문자의 UTF-8 인코딩이 128보다 높은 바이트코드를 사용하고 와이드 문자 라이브러리에서 사용되는 로케일 지원이 없으면 바이트를 와이드 문자로 재조립할 수 없다는 결과를 얻게 된다는 것입니다. 특징.
다음을 포함하는 Arch Linux(참고 참고)와 같은 일부 다른 플랫폼도 -lncurses
의 별칭으로 표시됩니다 .-lncursesw
/usr/lib/ncurses.so
INPUT(-lncursesw)
또 다른 댓글에서는 "두꺼운 선"에 대해 질문했습니다. 다음은 몇 가지 사항입니다.
- 내 대답에이중선 box_draw 문자를 터미널에, 나는 ncurses가 유니코드 사용을 용이하게 하는 기호를 제공한다고 언급했습니다.두꺼운그리고더블철사.
- 그것들은 이미 ncurses에 있습니다2009년 10월:
저는 일반적인 이유로 두꺼운/이중선 WACS_xxx 표기법만 구현했습니다. 이는 실험적이며 유니코드에만 유용합니다.
- 이 기호는 다음과 같이 기록됩니다.
wadd_wch
맨 페이지. - 이 기능은 MacOS용 번들 ncurses에서는 작동하지 않습니다. 해당 버전(ncurses 5.7)이 ncurses 변경 사항보다 약 1년 앞서기 때문입니다.
- Linux 콘솔 터미널에서는 작동하지 않습니다(512개의 글리프만 있는 글꼴에 의존하기 때문입니다).
- 실제로모습굵은 선/이중 선의 수는 지정되지 않습니다(글꼴에 따라 다름).
답변3
문제는 Linux 터미널에서 상자 문자가 올바르게 표시되지 않는다는 것입니다. 해결책은 코드를 다르게 컴파일해야 한다는 것입니다.
ncurses를 라이브러리로 사용하여 ncurses나 다른 텍스트 표시 방법을 사용하는 경우 printw
이것이 적용됩니다. 이는 OS에 따라 다르므로 macOS를 사용하는 경우 -lncurses
컴파일할 때 해당 플래그를 사용합니다(@terdon에 따라 이는 다음에도 적용됩니다).아키텍처Linux, 그러나 아직 테스트하지 않았습니다.) Linux를 사용하는 경우(Debian만 테스트했습니다) 해당 -lncursesw
플래그를 사용해야 합니다.
이 문제와 자동으로 코드가 상호 호환되도록 하려면 해당 코드를 makefile에 넣으세요.
ifneq ($(OS),Windows_NT)
UNAME_S := $(shell uname -s)
ifeq ($(UNAME_S),Linux)
NCURSES += -lncursesw
endif
ifeq ($(UNAME_S),Darwin)
NCURSES += -lncurses
endif
endif