문제

파일을 인수로 사용하는 응용 프로그램에 대한 작은 래퍼를 작성하고 있습니다.

래퍼는 유니 코드에 있어야하므로 캐릭터와 문자열에 WCHAR_T를 사용하고 있습니다. 이제 나는 문제가 있는데, 나는 wchar_t의 배열과 WCHAR_T 문자열에 프로그램의 인수를 가져야한다.

가능합니까? 나는 정의하고있다 main 기능

int main(int argc, char *argv[])

WCHAR_T를 사용해야합니까? argv?

대단히 감사합니다. C에서 유니 코드를 올바르게 사용하는 방법에 대한 유용한 정보를 찾지 못하는 것 같습니다.

도움이 되었습니까?

해결책

일반적으로 아니요. O/S에 따라 다르지만 C 표준은 'main ()'에 대한 인수는 'main (int argc, char ** argv)이어야하거나 동등한 것이기 때문에 char and wchar_t가 동일한 기본 유형이 아니라면 , 당신은 그것을 할 수 없습니다.

말하면, UTF-8 인수 문자열을 프로그램에 넣고 UTF-16 또는 UTF-32로 변환 한 다음 인생을 계속할 수 있습니다.

Mac (10.5.8, Leopard)에서는 다음과 같습니다.

Osiris JL: echo "ï€" | odx
0x0000: C3 AF E2 82 AC 0A                                 ......
0x0006:
Osiris JL: 

그것은 모두 UTF-8 인코딩되었습니다. (ODX는 HEX 덤프 프로그램입니다).

또한보십시오: UNIX/Linux 환경과 상호 작용할 때 UTF-8 인코딩이 사용되는 이유는 무엇입니까?

다른 팁

휴대용 코드는 지원하지 않습니다. Windows (예를 들어)는 사용을 지원합니다 wmain 대신에 main,이 경우 ArgV는 넓은 문자로 전달됩니다.

Windows에서 사용할 수 있습니다 GetCommandLineW() 그리고 CommandLineToArgvW() Argv 스타일을 생산합니다 wchar_t[] 앱이 유니 코드 용으로 컴파일되지 않더라도 배열.

어쨌든 창문에서는 a를 가질 수 있습니다 wmain() 유니 코드 빌드 용. 그래도 휴대용이 아닙니다. GCC 또는 UNIX/LINUX 플랫폼이 비슷한 것을 제공하는 경우에도 모릅니다.

Linux 환경이 UTF-8 인코딩을 사용한다고 가정하면 다음 코드는 C ++에서 쉽게 유니 코드 처리를 위해 프로그램을 준비합니다.

    int main(int argc, char * argv[]) {
      std::setlocale(LC_CTYPE, "");
      // ...
    }

다음으로, WCHAR_T 유형은 Linux에서 32 비트이므로 개별 유니 코드 코드 포인트를 보유 할 수 있으며 C ++ (문자 별 문자)의 클래식 스트링 처리에 WSTRING 유형을 안전하게 사용할 수 있습니다. 위의 SetLocale 호출을 사용하면 WCOUT에 삽입하면 출력이 자동으로 UTF-8으로 변환되고 WCIN에서 추출하면 UTF-8 입력이 UTF-32 (1 문자 = 1 코드 포인트)로 자동으로 변환됩니다. 남아있는 유일한 문제는 argv [i] 줄이 여전히 UTF-8 인코딩된다는 것입니다.

다음 함수를 사용하여 UTF-8을 UTF-32로 디코딩 할 수 있습니다. 입력 문자열이 손상되면 UTF-8 규칙이 파손 된 장소까지 올바르게 변환 된 문자를 반환합니다. 더 많은 오류보고가 필요한 경우 개선 할 수 있습니다. 그러나 ARGV 데이터의 경우 UTF-8이 올바른 것으로 가정 할 수 있습니다.

#define ARR_LEN(x) (sizeof(x)/sizeof(x[0]))

    wstring Convert(const char * s) {
        typedef unsigned char byte;
        struct Level { 
            byte Head, Data, Null; 
            Level(byte h, byte d) {
                Head = h; // the head shifted to the right
                Data = d; // number of data bits
                Null = h << d; // encoded byte with zero data bits
            }
            bool encoded(byte b) { return b>>Data == Head; }
        }; // struct Level
        Level lev[] = { 
            Level(2, 6),
            Level(6, 5), 
            Level(14, 4), 
            Level(30, 3), 
            Level(62, 2), 
            Level(126, 1)
        };

        wchar_t wc = 0;
        const char * p = s;
        wstring result;
        while (*p != 0) {
            byte b = *p++;
            if (b>>7 == 0) { // deal with ASCII
                wc = b;
                result.push_back(wc);
                continue;
            } // ASCII
            bool found = false;
            for (int i = 1; i < ARR_LEN(lev); ++i) {
                if (lev[i].encoded(b)) {
                    wc = b ^ lev[i].Null; // remove the head
                    wc <<= lev[0].Data * i;
                    for (int j = i; j > 0; --j) { // trailing bytes
                        if (*p == 0) return result; // unexpected
                        b = *p++;   
                        if (!lev[0].encoded(b)) // encoding corrupted
                            return result;
                        wchar_t tmp = b ^ lev[0].Null;
                        wc |= tmp << lev[0].Data*(j-1);
                    } // trailing bytes
                    result.push_back(wc);
                    found = true;
                    break;
                } // lev[i]
            }   // for lev
            if (!found) return result; // encoding incorrect
        }   // while
        return result;
    }   // wstring Convert

Windows에서는 tchar.h 및 _tmain을 사용할 수 있습니다. _unicode 기호가 컴파일 시간에 정의되거나 그렇지 않으면 주된 경우 wmain으로 바뀝니다. TCHA * argv []는 유니 코드가 정의 된 경우 WCHAR * argv []로 유사하게 확장되고, 그렇지 않은 경우 char * argv [].

주요 방법 작업 크로스 플랫폼을 원한다면 자신의 매크로를 동일한 효과로 정의 할 수 있습니다.

TCHAR.H에는 WCHAR과 Char 간의 전환을위한 여러 편의 매크로가 포함되어 있습니다.

라이센스 : CC-BY-SA ~와 함께 속성
제휴하지 않습니다 StackOverflow
scroll top