애플리케이션이 입력 문자를 가져오려고 합니다.

애플리케이션이 입력 문자를 가져오려고 합니다.

일부 언어에는 넓은 문자가 있습니다. 와이드 문자는 여러 바이트를 가질 수 있습니다. 콘솔이나 X에 와이드 문자를 입력하면 실제로 몇 바이트를 보내는 것입니다. 단일 바이트 문자는 전송되거나 수신되지 않거나 수신되거나 수신되지 않는다는 의미에서 그 자체로 원자적입니다. 하지만 와이드 문자의 경우에는 그렇지 않습니다. 예를 들어, 3바이트 문자의 첫 번째 바이트만 전송하면 가비지가 생성됩니다. 기본 시스템은 애플리케이션이 항상 자동으로 와이드 문자를 수신하도록 어떻게 보장합니까? 좋은 답변은 사용자가 콘솔, X, SSH에서 각각 와이드 문자를 입력할 때 어떤 일이 발생하는지 설명해야 합니다. 시작 스토리: 사용자가 와이드 문자를 입력하면 인터럽트가 발생합니다...


기본 시스템은 애플리케이션이 항상 자동으로 와이드 문자를 수신하도록 어떻게 보장합니까?

스택에 여러 레이어가 있기 때문에 이 질문의 용어는 일부 사람들에게 혼란스러울 수 있습니다. 내가 실제로 의미하는 바는 다음과 같습니다. 편집 상자가 있는 GUI 애플리케이션을 작성한다고 생각해 보십시오. 와이드 문자를 입력하면 완전히 표시되거나 표시되지 않고 부분적으로 표시되지 않습니다. 따라서 기본 시스템에는 애플리케이션 아래의 모든 항목(이 경우 애플리케이션 프레임워크, GUI 라이브러리 등)이 포함됩니다.

답변1

그렇지 않습니다.

(텍스트) 애플리케이션은 표준 입력에서 바이트 스트림을 받습니다. 이 앱을 사용하면 원하는 만큼 많은 콘텐츠를 읽을 수 있습니다.호출은 read요청된 것보다 적은 바이트를 자유롭게 반환합니다..이 바이트 스트림은 원하는 대로 해석될 수 있습니다., 더 많은 바이트 읽기를 요청하거나 모든 것을 불투명한 이진 데이터로 처리합니다. 특정 바이트를 다른 개별 블록의 일부로 해석하려는 경우 그렇게 할 수 있으며 블록을 소유한다고 결정할 때까지 계속 검색할 수 있습니다.한 번에 모든 것을 얻을 수 있다는 보장은 없습니다.바이트가 아닌 한.

여기에 짧은 대답이 있습니다. 원한다면 지금 읽지 않아도 됩니다. 응용 프로그램이 선택한 결과를 얻기 위해 원하는 모든 작업을 수행할 수 있을 때까지 질문의 전제는 거짓입니다.

아래에서는 일이 발생할 수 있는(또는 발생하지 않을 수 있는) 몇 가지 방식과 누군가의 관점에서 "원자적"일 수 있거나 발생하지 않을 수 있는 경우에 대해 계속 논의하겠습니다.


이 답변의 나머지 부분에서는 네트워크 및 소켓 트래픽을 무시합니다. 우리는 또한 "역할"에 대한 다소 모호한 정의를 채택할 것입니다. 이것이 출발점인 것처럼 보이고 앞으로 나아갈 가능성이 높기 때문입니다. 우리는 최종 애플리케이션의 관점에서 문제를 고려할 것입니다. 마지막으로 키보드 하드웨어의 (주로 주제에서 벗어난) 경로를 간략하게 살펴보겠습니다. 아직 너무 깁니다.


애플리케이션이 입력 문자를 가져오려고 합니다.

애플리케이션에는 read입력에서 일부 바이트가 필요합니다. 그런 다음 수신한 바이트를 원하는 방식으로 자유롭게 해석하거나 라이브러리에서 그렇게 하도록 할 수도 있습니다. 텍스트가 필요한 경우 이러한 바이트를 어떤 방식으로 해석합니다.문자 인코딩, 바이트 시퀀스의 의미를 결정합니다. 사용된 인코딩에 대한 데이터 소스 또는 터미널과 일치하기를 바랍니다(그러나 필수는 아닙니다!). 모든 인코딩과 마찬가지로 애플리케이션은 사물을 다음과 같이 해석하기로 결정합니다.

  • 해당 인코딩이 ASCII라면 어쨌든 모든 것이 단일 바이트이므로 모든 것이 괜찮습니다.

  • 인코딩이 UCS-2인 경우 16비트의 경우 wchar_t필요한 경우 다른 바이트를 요청할 수 있도록 읽은 ​​바이트 수를 아는 것이 더 좋습니다( read언제든지 홀수 바이트가 반환될 수 있으므로 코드의 절반이 제공됩니다). 단위).

  • 인코딩이 다음과 같은 경우UTF-9, 코드 단위를 꺼내려면 자체적으로 일부 수정이 필요할 수 있으며 최신 시스템에서 이를 원자적으로 전달하는 것은 거의 불가능합니다.

  • 해당 인코딩이 KEIS인 경우 시퀀스 해석은 스트림 초기의 상태 저장 모드 전환에 따라 달라지므로 예상한 수준의 원자 전달도 불가능합니다. 애플리케이션은 이 입력이 무엇을 의미하는지 알기 위해 이미 본 내용을 기억해야 합니다.

  • 인코딩이 다음과 같은 경우UTF-8요즘 애플리케이션은 동기화를 위해 단일 바이트를 사용할 가능성이 높습니다.자체 동기 인코딩입니다.: 단일 바이트 코드 단위의 경우 다중 바이트 시퀀스의 모든 부분에 대한 상위 비트는 0이고 상위 비트는 1입니다. 2, 3 또는 4바이트 코드 단위의 첫 번째 바이트는 각각 110, 1110 또는 11110이며 후속 바이트는 10에서 시작합니다. 바이트를 읽으면 더 많은 바이트가 필요한지 또는 이미 작업 중인지 알 수 있습니다.

    필요하신 경우 신청하시면 됩니다그럼 하나 만들어 보고 싶을 수도 있겠네요두번째 read다음 바이트에 대해. 어떤 부분 요소를 읽었는지 기억하고 마지막에 두 부분을 결합해야 합니다. 세 번째 또는 네 번째 읽기가 필요할 수도 있습니다.

    그런 다음 필요에 따라 개별적으로 처리할 수 있으며 코드 포인트에 대해 단일 32비트 값을 내보낼 수도 있습니다. 재사용을 위해 함수나 라이브러리로 추상화하는 것이 현명할 수 있습니다.

이러한 속성과 그 이상을 모두 갖춘 다른 인코딩이 있습니다. 이들 중 일부는 POSIX에서 시스템 인코딩으로 허용되지 않지만 애플리케이션 간에 합의될 수 있습니다. 현재 Unix 계열 시스템에서 멀티바이트 시스템 인코딩을 사용하고 있다면 UTF-8일 가능성이 높습니다.


그런데 역할이 정확히 뭔가요?

내 멀티바이트 문자 "é"는 UTF-8의 2바이트(C3 A9) 또는 3바이트(65 CC 81)일 수 있습니다. 이는 단일 코드 포인트(ACUTE가 포함된 U+00E9 LATIN SMALL LETTER E) 또는 2바이트(U)일 수 있기 때문입니다. +0065 라틴어 소문자 E + U+0301 결합된 예음). "

관련 정보