쉘을 호출하는 동안 잘못된 인코딩


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 이라고 가정합니다 . 또한 쉘 / cmd를 호출 할 때 파일 이름이 다른 인코딩으로 해석되고 있다고 가정합니다 ( 기본적으로 코드 페이지 850 을 지적한 Carpetsmoker 덕분에 ).

이 문제를 어떻게 해결할 수 있습니까?

물론 파일 이름을 바꿀 수는 있지만 왜 이런 일이 발생하고 어떻게 수정해야하는지 알고 싶습니다.

업데이트 : 방금 수퍼 유저 .SE (@ ChristianBrabandt의 피드백 덕분에) 에서이 질문 을 찾았 지만 도움이되지 않는 것 같습니다.


1
Cygwin 또는 MobaXterm (Windows의 휴대용 Unix와 유사한 환경)의 명령 줄에서 Vim을 사용하여 동일한 오류가 발생하는지 궁금합니다. 나는 의심하지 않는다. 실제로이 문제를 해결 하는 방법이있을 수 있으므로 Windows cmd는 파일 이름을 허용하지만 Unix와 같은 환경을 설치하는 것이 내가 선호하는 처리 방법입니다.
와일드 카드

2
내가 읽은 것의 기본값 cmd.exe은 유니 코드가 아니라 코드 페이지 850 입니다. 이 답변도 참조하십시오 .
Martin Tournoij

@Carpetsmoker에게 감사합니다. 귀하가 제공 한 정보로 내 질문을 자유롭게 업데이트했습니다.
Roflo

나는 확실하지 않지만 'termencoding'옵션을 조정하고 싶을 수도 있습니다.
Christian Brabandt

@ChristianBrabandt 내가 잘못하고 있지 않으면 도움이되지 않는 것 같습니다. tenc를 latin1, utf8 및 cp850으로 설정하려고했습니다. 트릭을 수행하는 사람은 없습니다.
Roflo

답변:


2

짧은 답변

문제는에 dot.exe있습니다. GraphViz는 Linux에서 유니 코드 경로가있는 파일을 열 수 있지만 Visual Studio 2005로 컴파일 된 경우가 아니면 Windows에서는 불가능합니다.

연구

코드 페이지가 850, Vim 인코딩으로 설정 되어 UTF-8있습니다.

여기에 이미지 설명을 입력하십시오

정확히 같은 오류는 없지만 dot.exe잘못된 인수를받는 것으로 보입니다. 같은 파일 이름을 다른 프로그램으로 전달하려고했습니다.

여기에 이미지 설명을 입력하십시오

그리고 그것은 제대로 작동했습니다. 직접 실행 dot.exe하고 type직접 실행 cmd.exe하면 동일한 결과를 얻을 수 있으므로 Windows 콘솔이나 Vim 모두 문제가되지 않습니다. 그 오류를 일으킬 수있는 다음 것은 그 dot.exe자체였습니다. 내 콘솔 코드조차도 유니 코드 코딩 인수를 올바르게 처리하는 방법을 모른다는 의혹이 있었다.

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

완전한 유니 코드 지원이 필요한 경우 PowerShell을 사용하십시오. CMD 셸에서 유니 코드에 대한 지원은 여전히 ​​매우 제한적이며 파이핑, 리디렉션 및 대부분의 명령은 여전히 ​​ANSI 전용입니다. 작동하는 유일한 명령은 DIR, FOR / F 및 TYPE이며, 이는 파일 및 파일 이름을 읽고 쓸 수 있지만 (UTF-16LE / BOM) 다른 것은 아닙니다.

GraphViz에서 유니 코드를 지원하는 경우 웹을 검색하여 유니 코드 파일을 지원 하지만 파일 이름의 유니 코드 지원 은 지원하지 않는 것으로 나타났습니다 . GraphViz 버그 트래커에 대한 보고서 나 포럼에서 유니 코드라는 이름의 파일을 읽는 데 관심이있는 사람에 대한 게시물을 찾지 못했습니다. 그래서 나는 그것을 소스에서 찾았습니다. 여기에 무엇 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 기능은 파일 이름에 의해 지정된 파일을 엽니 다. _wfopen 은 와이드 문자 버전의 fopen입니다 . _wfopen에 대한 인수 는 와이드 문자 스트링입니다. _wfopenfopen은 다르게 동작합니다. 단순히 _wfopen 을 사용하더라도 파일 스트림에 사용 된 코딩 된 문자 세트에는 영향을 미치지 않습니다.

Visual C ++ 2005에서 fopen은 유니 코드 파일 스트림을 지원합니다.

슬프게도, 유일한 옵션은 파일 이름을 바꾸는 것입니다.

당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.