【あるあるbot連動企画】フォロワー20万人のアカウントであなたのあるあるを披露してみませんか?

Linux Red Hat 6.1 を使っています。
cursesライブラリを使用して、linuxconf のようなウィザードを造っています。
半角カナの扱いで今困っています。

mvprintw(10, 16, "aaaaaaaaaaaa");
mvprintw(11, 16, "aaaaaaaaaaaa");
refresh();

[補足]
・上記の mvprintw()関数は、仮想画面に書く関数です。
printf()みたいなものです。
数字は左上を (0,0)原点としたXY座標で、その位置から書かれます。
refresh()関数は仮想画面を物理画面に描画して、目視できるようになります。
・上記では文字化けするといけないので、「a」としています。
「a」:半角カナの「ア」
と解釈してください。

[結果]
上記のように実行すると、2行目の表示がおかしくなります。
2行目は (11, 16) から書き出す要求をしているにもかかわらず、行頭からの
表示となってしまいます。

---------------aaaaaaaaaaaa
aaaaaaaaaaaa

「-」は空白です。

kterm 上でいろいろ試したところ、なぜか kterm のライン数を大きくすると
この現象が回避されました。
因果関係は全くわからず、また、ライン数を大きくする以外の回避策も
見つからず困っています。

<追加情報です>
ktermのライン数は同じのまま、Y座標を変えて、(10, 15), (11, 15) と
したところ正常に表示されました。
Y座標が「15以下」だと正常に表示されるみたいです。
ますます原因がわからない。。。

識者の方、ご教授願います。

A 回答 (2件)

OKとなる場合、「ア」の行を書いたあと、「イ」を書く座標を明


示的に指定してジャンプしているので、問題なく表示されています。

これに対して、NGとなる場合、「ア」を10個書いたあと、1行下
に移動("LF" = 0A)し、20桁左に移動("ESC [ 2 0 D" = 1B 5B 32
30 44)しています。

半角カナを10個書いて20桁左に行くので、戻りすぎてしまい、表示
がおかしくなるようです。curses が、半角カナが1桁分の幅しかな
いことを認識していないということですね。

なぜ、kterm の大きさや座標の微妙な差で、結果に違いがあるのか
というと、curses は、同じ表示になるなら、なるべく短い出力を
出すように工夫するからです。ちょっとした出力文字数の差で、違
うやり方を選択するので、偶然うまく行ったりいかなかったりする
わけです。(もっとも、本当に最適かどうかはわかりません。この
例では、どの場合でも、直接座標を指定するのは文字数的に損して
る気がします。)

linux の JE というパッケージに、日本語化された pcurses とい
うのが入っているらしいですが、詳しくは知りません。日本語化さ
れたといっても、半角カナが扱えない可能性も高いです。

もし、これを入れてみてもだめなら、半角カナにはこだわらない方
がいいかと思います。あるいは、curses をやめて、termcap を直
接いじるかですね。

この回答への補足

punchan_jp さん、解析、アドバイスありがとうございました。
とても参考になりました。
原因がわからなかったためモヤモヤしていましたが、原因がわかって
すっきりしました。
私の方もいろいろ試したところ、なんとか回避できそうです。
curses が明示的に座標にジャンプする/しないの条件はわからないのですが、
行の最後で改行コードを入れるとOKみたいです。
実際のコードでは、半角カナのデータを仮想画面に書いた後
mvprintw(x, (COLS - 1), "\n");
としました。
で、refresh() 関数で物理画面に描画すれば乱れませんでした。
ただし、半角カナのデータの最後に「\n」を付加した場合は駄目でした。
あと、refresh() 前に move() 関数でカーソル移動させるとカーソル位置が
乱れてしまいました。
カーソル移動は物理描画後にしました。

UNIX、Linux では半角カナを使わないのがいいんですが、どうしても
使わなきゃいけなかったので苦労しました。。。

本当にご協力ありがとうございました。
感謝します。

補足日時:2001/04/05 18:36
    • good
    • 0

半角カナでなく、ASCII 文字なら問題ないのでしょうか?


出力する文字コードと kterm の文字コードの設定として
何を使っているでしょうか?
EUC を使っているとすると、半角カナは2バイトで表現されますから、
ちゃんと日本語化された curses でないと正しく扱えないかもしれません。

あとは、kterm のバグが考えられますが、この場合、script コマンドによって
curses がどのような出力をしているかの生の情報を収集できます。
script を起動して、すぐ問題のコマンドを動かし、おかしくなっ
た時点ですぐ終了させて、script も exit で抜けておきます。
そうすれば、typescript というファイルに、それまでに出力され
たバイト列が生成されます。これを適当な方法で解析してください。
うまくいく場合といかない場合の両方を調べて比較するといいかもしれません。

このファイルが巨大でなければ、cat -vt してここに掲載してもらえれば、
調べてみますけど。

この回答への補足

punchan_jp さん、回答ありがとうございました。
ご質問に対してお答えします。
#長くなっちゃったけど大丈夫かなぁ。。。

>半角カナでなく、ASCII 文字なら問題ないのでしょうか?
・ASCII 文字、全角文字なら問題ありません。

>出力する文字コードと kterm の文字コードの設定として
>何を使っているでしょうか?
・出力コードはEUCです。
kterm の文字コードの設定というのは、LANG、LC_ALL のことで
いいのでしょうか。
どちらも ja_JP.ujis となっていました。

>EUC を使っているとすると、半角カナは2バイトで表現されますから、
>ちゃんと日本語化された curses でないと正しく扱えないかもしれません。
・データは2バイトですが、1バイト分で表示されています。
ちゃんと日本語化された curses ライブラリかどうか判断することは
できますか?
6.1 でのリンクは以下のようになっていました。
libcurses.so -> libncurses.so
libncurses.so -> libncurses.so.4
libncurses.so.4 -> libncurses.so.4.2
libncurses.so.4.2 : (1999 Sep 24 274985byte)

ちなみに 6.2 でも同じ現象になりました。
実体は libncurses.so.4.0 (2000 Mar 7 262884 byte) でした。

>あとは、kterm のバグが考えられますが、この場合、script コマンドによって
>curses がどのような出力をしているかの生の情報を収集できます。
>script を起動して、すぐ問題のコマンドを動かし、おかしくなっ
>た時点ですぐ終了させて、script も exit で抜けておきます。
>そうすれば、typescript というファイルに、それまでに出力され
>たバイト列が生成されます。これを適当な方法で解析してください。
>うまくいく場合といかない場合の両方を調べて比較するといいかもしれません。

参考までに、簡単なプログラムを以下に載せておきます。
-------------------- ここから --------------------
#include <curses.h>
main()
{
char tbl_1[80];
char tbl_2[80];
int cnt, cnt2;
int mojiCnt = 10;

initscr();
clear();

memset(tbl_1, '\0', 80);
memset(tbl_2, '\0', 80);

for (cnt = 0, cnt2 = 0; cnt < mojiCnt; cnt++) {
tbl_1[cnt2] = 0x8E;
tbl_2[cnt2] = 0x8E;
cnt2++;
tbl_1[cnt2] = 0xB1;
tbl_2[cnt2] = 0xB2;
cnt2++;
}

mvprintw(10, 16, "%s", tbl_1);
mvprintw(11, 16, "%s", tbl_2);
refresh();
endwin();
}
-------------------- ここまで --------------------

質問を出した後、いろいろ試しましたが、以下の条件が影響すると
わかりました。
・書き出すY座標
・表示する文字数
・kterm のライン数

プログラムで、文字数(mojiCnt)、Y座標(mvprintw 関数の第2パラメータ)を
変更したり、kterm のライン数を変えてテストしました。
例えば上記プログラムは、ライン数:24、カラム:80 の kterm で実行すると
NGですが、ライン数を 25 にするとOKでした。
また、ライン数:24、カラム:80 のままで、座標を (10,15) と (11,15) と
したらOKでした。
データ長にも影響しているらしく、各行2文字ずつ表示した場合、Y座標が
2以下ならOKで、3以上がNGでした。
各行3文字の場合は、Y座標が3以下がOKで、4以上だとNGでした。
(ライン数:24、カラム:80)

Windows のマシンから「TeraTerm」というソフトで telnet して試しましたが
同じ現象が発生しました。
この場合は、LANG、ロケールは ja_JP.eucJP です。
なので curses の問題だとは思うのですが、原因が全く推測できません。


>このファイルが巨大でなければ、cat -vt してここに掲載してもらえれば、
>調べてみますけど。

お時間が許されるならば、よろしくお願いします。
以下が cat の結果とダンプデータです。

cat の結果をファイルに落として vi で見たところ、NGとなった (1) の
場合は1行目の表示と2行目の表示のデータの部分は別の行となっていましたが
OKの場合は1行目の表示と2行目の表示のデータの部分は同じ行として
つながっていました。
ダンプデータを見ると確かに (1) は 1行目のデータの後ろに 0x0A の
改行コードがあり、(2)、(3) では0x0A の改行コードがありませんでした。


(1)上記プログラムを実行(ライン数:24、カラム:80)
結果=>NG
<cat -vt データ>
[nabe@upsx3 testkana]$ cat -vt type16-24
M-%M-9M-%M-/M-%M-jM-%M-WM-%M-HM-$M-O Wed Apr 4 15:47:27 2001
M-$M-KM-3M-+M-;M-OM-$M-7M-$M-^M-$M-7M-$M-?[nabe@upsx3 testkana]$ a.out^M
^[7^[[?47h^[[1;24r^[[m^[[4l^[[H^[[2J^[[11;17HM-^NM-1M-^NM-1M-^NM-1M-^NM-1M-^NM-1M-^NM-1M-^NM-1M-^NM-1M-^NM-1M-^NM-1
^[[20DM-^NM-2M-^NM-2M-^NM-2M-^NM-2M-^NM-2M-^NM-2M-^NM-2M-^NM-2M-^NM-2M-^NM-2^[[24;1H^[[2J^[[?47l^[8^M^[[?1l^[>[nabe@upsx3 testkana]$ exit^M
exit^M

M-%M-9M-%M-/M-%M-jM-%M-WM-%M-HM-$M-O Wed Apr 4 15:47:45 2001
M-$M-KM-=M-*M-NM-;M-$M-7M-$M-^M-$M-7M-$M-?[nabe@upsx3 testkana]$

<ダンプデータ>
00000000 A5 B9 A5 AF A5 EA A5 D7 A5 C8 A4 CF 20 57 65 64
00000010 20 41 70 72 20 20 34 20 31 35 3A 34 37 3A 32 37
00000020 20 32 30 30 31 0A 20 A4 CB B3 AB BB CF A4 B7 A4
00000030 DE A4 B7 A4 BF 5B 6E 61 62 65 40 75 70 73 78 33
00000040 20 74 65 73 74 6B 61 6E 61 5D 24 20 61 2E 6F 75
00000050 74 0D 0A 1B 37 1B 5B 3F 34 37 68 1B 5B 31 3B 32
00000060 34 72 1B 5B 6D 1B 5B 34 6C 1B 5B 48 1B 5B 32 4A
00000070 1B 5B 31 31 3B 31 37 48 8E B1 8E B1 8E B1 8E B1
00000080 8E B1 8E B1 8E B1 8E B1 8E B1 8E B1 0A 1B 5B 32
00000090 30 44 8E B2 8E B2 8E B2 8E B2 8E B2 8E B2 8E B2
000000A0 8E B2 8E B2 8E B2 1B 5B 32 34 3B 31 48 1B 5B 32
000000B0 4A 1B 5B 3F 34 37 6C 1B 38 0D 1B 5B 3F 31 6C 1B
000000C0 3E 5B 6E 61 62 65 40 75 70 73 78 33 20 74 65 73
000000D0 74 6B 61 6E 61 5D 24 20 65 78 69 74 0D 0A 65 78
000000E0 69 74 0D 0A 0A A5 B9 A5 AF A5 EA A5 D7 A5 C8 A4
000000F0 CF 20 57 65 64 20 41 70 72 20 20 34 20 31 35 3A
00000100 34 37 3A 34 35 20 32 30 30 31 0A 20 A4 CB BD AA
00000110 CE BB A4 B7 A4 DE A4 B7 A4 BF

(2)上記プログラムを実行(ライン数:25、カラム:80)
結果=>OK
<cat -vt データ>
[nabe@upsx3 testkana]$ cat -vt type16-25
M-%M-9M-%M-/M-%M-jM-%M-WM-%M-HM-$M-O Wed Apr 4 15:49:58 2001
M-$M-KM-3M-+M-;M-OM-$M-7M-$M-^M-$M-7M-$M-?[nabe@upsx3 testkana]$ a.out^M
^[7^[[?47h^[[1;25r^[[m^[[4l^[[H^[[2J^[[11;17HM-^NM-1M-^NM-1M-^NM-1M-^NM-1M-^NM-1M-^NM-1M-^NM-1M-^NM-1M-^NM-1M-^NM-1^[[12;17HM-^NM-2M-^NM-2M-^NM-2M-^NM-2M-^NM-2M-^NM-2M-^NM-2M-^NM-2M-^NM-2M-^NM-2^[[25;1H^[[2J^[[?47l^[8^M^[[?1l^[>[nabe@upsx3testkana]$ exit^M
exit^M

M-%M-9M-%M-/M-%M-jM-%M-WM-%M-HM-$M-O Wed Apr 4 15:50:13 2001
M-$M-KM-=M-*M-NM-;M-$M-7M-$M-^M-$M-7M-$M-?[nabe@upsx3 testkana]$

<ダンプデータ>
00000000 A5 B9 A5 AF A5 EA A5 D7 A5 C8 A4 CF 20 57 65 64
00000010 20 41 70 72 20 20 34 20 31 35 3A 34 39 3A 35 38
00000020 20 32 30 30 31 0A 20 A4 CB B3 AB BB CF A4 B7 A4
00000030 DE A4 B7 A4 BF 5B 6E 61 62 65 40 75 70 73 78 33
00000040 20 74 65 73 74 6B 61 6E 61 5D 24 20 61 2E 6F 75
00000050 74 0D 0A 1B 37 1B 5B 3F 34 37 68 1B 5B 31 3B 32
00000060 35 72 1B 5B 6D 1B 5B 34 6C 1B 5B 48 1B 5B 32 4A
00000070 1B 5B 31 31 3B 31 37 48 8E B1 8E B1 8E B1 8E B1
00000080 8E B1 8E B1 8E B1 8E B1 8E B1 8E B1 1B 5B 31 32
00000090 3B 31 37 48 8E B2 8E B2 8E B2 8E B2 8E B2 8E B2
000000A0 8E B2 8E B2 8E B2 8E B2 1B 5B 32 35 3B 31 48 1B
000000B0 5B 32 4A 1B 5B 3F 34 37 6C 1B 38 0D 1B 5B 3F 31
000000C0 6C 1B 3E 5B 6E 61 62 65 40 75 70 73 78 33 20 74
000000D0 65 73 74 6B 61 6E 61 5D 24 20 65 78 69 74 0D 0A
000000E0 65 78 69 74 0D 0A 0A A5 B9 A5 AF A5 EA A5 D7 A5
000000F0 C8 A4 CF 20 57 65 64 20 41 70 72 20 20 34 20 31
00000100 35 3A 35 30 3A 31 33 20 32 30 30 31 0A 20 A4 CB
00000110 BD AA CE BB A4 B7 A4 DE A4 B7 A4 BF

(3)上記プログラムを (10,15) (11,15) から書き出すように修正して実行
(ライン数:24、カラム:80)
結果=>OK
<cat -vt データ>
[nabe@upsx3 testkana]$ cat -vt type15-24
M-%M-9M-%M-/M-%M-jM-%M-WM-%M-HM-$M-O Wed Apr 4 15:51:54 2001
M-$M-KM-3M-+M-;M-OM-$M-7M-$M-^M-$M-7M-$M-?[nabe@upsx3 testkana]$ a.out^M
^[7^[[?47h^[[1;24r^[[m^[[4l^[[H^[[2J^[[11;16HM-^NM-1M-^NM-1M-^NM-1M-^NM-1M-^NM-1M-^NM-1M-^NM-1M-^NM-1M-^NM-1M-^NM-1^[[12;16HM-^NM-2M-^NM-2M-^NM-2M-^NM-2M-^NM-2M-^NM-2M-^NM-2M-^NM-2M-^NM-2M-^NM-2^[[24;1H^[[2J^[[?47l^[8^M^[[?1l^[>[nabe@upsx3testkana]$ exit^M
exit^M

M-%M-9M-%M-/M-%M-jM-%M-WM-%M-HM-$M-O Wed Apr 4 15:52:05 2001
M-$M-KM-=M-*M-NM-;M-$M-7M-$M-^M-$M-7M-$M-?[nabe@upsx3 testkana]$

<ダンプデータ>
00000000 A5 B9 A5 AF A5 EA A5 D7 A5 C8 A4 CF 20 57 65 64
00000010 20 41 70 72 20 20 34 20 31 35 3A 35 31 3A 35 34
00000020 20 32 30 30 31 0A 20 A4 CB B3 AB BB CF A4 B7 A4
00000030 DE A4 B7 A4 BF 5B 6E 61 62 65 40 75 70 73 78 33
00000040 20 74 65 73 74 6B 61 6E 61 5D 24 20 61 2E 6F 75
00000050 74 0D 0A 1B 37 1B 5B 3F 34 37 68 1B 5B 31 3B 32
00000060 34 72 1B 5B 6D 1B 5B 34 6C 1B 5B 48 1B 5B 32 4A
00000070 1B 5B 31 31 3B 31 36 48 8E B1 8E B1 8E B1 8E B1
00000080 8E B1 8E B1 8E B1 8E B1 8E B1 8E B1 1B 5B 31 32
00000090 3B 31 36 48 8E B2 8E B2 8E B2 8E B2 8E B2 8E B2
000000A0 8E B2 8E B2 8E B2 8E B2 1B 5B 32 34 3B 31 48 1B
000000B0 5B 32 4A 1B 5B 3F 34 37 6C 1B 38 0D 1B 5B 3F 31
000000C0 6C 1B 3E 5B 6E 61 62 65 40 75 70 73 78 33 20 74
000000D0 65 73 74 6B 61 6E 61 5D 24 20 65 78 69 74 0D 0A
000000E0 65 78 69 74 0D 0A 0A A5 B9 A5 AF A5 EA A5 D7 A5
000000F0 C8 A4 CF 20 57 65 64 20 41 70 72 20 20 34 20 31
00000100 35 3A 35 32 3A 30 35 20 32 30 30 31 0A 20 A4 CB
00000110 BD AA CE BB A4 B7 A4 DE A4 B7 A4 BF

以上

補足日時:2001/04/04 16:41
    • good
    • 0

お探しのQ&Aが見つからない時は、教えて!gooで質問しましょう!


おすすめ情報