シェルを呼び出す際の誤ったエンコーディング


9

私はDOTダイアグラムを試し、次のことを試みました。

:! dot -Tpng -oFab.png %

ファイル名に特殊文字(ó「Fabricación」の「」)が含まれているため、エラーが発生しました。

C:\windows\system32\cmd.exe /c ( dot -Tpng -oFab.png Fabricaci├│n.gv)
Error: dot: can't open Fabricaci├│n.gv
shell returned 2
Hit any key to close this window...

ご覧のとおり、「├│」の特殊文字が変更されています。これは、Win7とNTFSでのvimとgVim 7.4に対応しているため、ファイル名はUTF16であると想定しています。また、shell / cmdを呼び出すときに、ファイル名が他のエンコードとして解釈されていると想定しています(デフォルトのコードページ850を指摘してくれたCarpetsmokerに感謝します)。

どうすれば修正できますか?

確かに、ファイルの名前を変更することはできますが、これが発生する理由と修正方法を知りたいのですが。

更新:私はこの質問をsuperuser.SEで見つけました(@ ChristianBrabandtによるフィードバックに感謝します)が、それも役に立たないようです。


1
CygwinまたはMobaXterm(Windows用の移植可能なUnixライクな環境)のコマンドラインでVimを使用しても同じエラーが発生するかどうか知りたいです。私はそうは思わない。これを実際に修正してWindows cmdがファイル名を受け入れる方法があるかもしれませんが、Unixのような環境をインストールすることは、私自身の優先する処理です。
ワイルドカード2016年

2
私が読んだことによると、のデフォルトcmd.exeはユニコードではなく、コードページ850です。この回答もご覧ください
Martin Tournoij 16

@Carpetsmokerに感謝します。私は自由にあなたの提供した情報で私の質問を更新しました。
ロフロ2016

完全にはわかりませんが、「termencoding」オプションを微調整することをお勧めします。
クリスチャンブラバンド

@ChristianBrabandt私が何か間違ったことをしていない限り、それは役に立たないようです。tencをlatin1、utf8、cp850に設定してみました。だれもトリックをするようではない。
ロフロ2016

回答:


2

簡潔な答え

問題はにありますdot.exe。GraphVizは、Visual Studio 2005でコンパイルした場合を除いて、LinuxではUnicodeパスを持つファイルを開くことができますが、Windowsではできません。

研究

コードページはに850、Vimエンコーディングはに設定されUTF-8ます。

ここに画像の説明を入力してください

まったく同じエラーは表示されませんが、dot.exeは間違った引数を受け取るようです。同じファイル名を他のプログラムに渡してみました。

ここに画像の説明を入力してください

そして、それはちょうどうまくいきました。両方dot.exetype直接実行してもcmd.exe同じ結果が得られるため、WindowsコンソールもVimも問題ありません。そのエラーを引き起こす可能性がある次のことはdot.exeそれ自体でした。私の疑いは、すべてのコンソールコマンドでさえもそうではないように、Unicodeでコード化された引数を適切に処理する方法がわからないことです。

https://ss64.com/nt/chcp.html

完全なUnicodeサポートが必要な場合は、PowerShellを使用してください。CMDシェル、パイピング、リダイレクトではUnicodeのサポートが非常に限定されており、ほとんどのコマンドはANSIのみです。動作するコマンドはDIR、FOR / F、およびTYPEのみです。これにより、ファイル(UTF-16LE / BOM)とファイル名の読み取りと書き込みが可能になりますが、それ以外のことはできません。

GraphVizでUnicodeがサポートされているかどうかをウェブで検索したところ、Unicode ファイルはサポートされていますが、ファイル名のUnicodeサポートについては何も見つかりませんでした。私は、GraphVizバグトラッカーに関する報告も、Unicodeという名前のファイルの読み取りに関心のある他の人に関するフォーラムへの投稿も見つかりませんでした。だから私はソースでそれを調べました。ここでは何であるdot.exeエントリポイントのルックスが好き:

graphviz-2.40.1\cmd\dot\dot.c

int main(int argc, char **argv)
{
    . . .

/* --------------------> ARGS ARE BEING PASSED HERE */
    gvParseArgs(Gvc, argc, argv);

    . . .

以下のargvウサギの穴の下:graphviz-2.40.1\lib\common\args.c

int gvParseArgs(GVC_t *gvc, int argc, char** argv)
{
    int rv;
    if ((argc = neato_extra_args(gvc, argc, argv)) < 0)    return (1-argc);
    if ((argc = fdp_extra_args(gvc, argc, argv)) < 0)      return (1-argc);
    if ((argc = memtest_extra_args(gvc, argc, argv)) < 0)  return (1-argc);
    if ((argc = config_extra_args(gvc, argc, argv)) < 0)   return (1-argc);

/* -------------------->  HERE GO ALL NON-FLAG ARTUMENTS */
    if ((rv = dotneato_args_initialize(gvc, argc, argv)))  return rv;

    if (Verbose) gvplugin_write_status(gvc);
    return 0;
}

graphviz-2.40.1\lib\common\input.c

int dotneato_args_initialize(GVC_t * gvc, int argc, char **argv)
{
    for (i = 1; i < argc; i++) {
        if (argv[i] && argv[i][0] == '-') {

            . . .

/* -------------------->  JUST CASUALLY COPYING CHAR POINTERS */
        } else if (argv[i])
            gvc->input_filenames[nfiles++] = argv[i];
    }

そして最後に graphviz-2.40.1\lib\common\input.c

graph_t *gvNextInputGraph(GVC_t *gvc)
{
    . . . .

/* -------------------->  OPENING THE FILES FOR READ WITH FOPEN */
    while ((fn = gvc->input_filenames[fidx++]) && !(fp = fopen(fn, "r")))  {

        . . .

    }

MDSNが述べるように:

fopen関数は、filenameで指定されたファイルを開きます。_wfopenfopenのワイド文字バージョンです。_wfopenの引数はワイド文字列です。それ以外の場合、_wfopenfopenの動作は同じです。_wfopenを単に使用しても、ファイルストリームで使用されるコード化文字セットには影響しません。

Visual C ++ 2005では、fopenはUnicodeファイルストリームをサポートしています。

悲しいことに、ファイルの名前を変更するしかありません。

弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.