2012-07-29 5 views
1
/* 
Low Level I/O - Read and Write 
Chapter 8 - The C Programming Language - K&R 
Header file in the original code is "syscalls.h" 
Also BUFSIZ is supposed to be defined in the same header file 
*/ 

#include <sys/types.h> 
#include <sys/uio.h> 
#include <unistd.h> 

#define BUFSIZ 1 

int main() /* copy input to output */ 
{ 
    char buf[BUFSIZ]; 
    int n; 

    while ((n = read(0, buf, BUFSIZ)) > 0) 
     write(1, buf, n); 

    return 0; 
} 

"ΣΣΣ † ¥₩₩ ˚πΔ~~ ∫ ∫ πν ~ 886661 ~ EOF"를 입력으로 입력하면 동일한 내용이 복사됩니다. 얼마나 많은 비 ASCII 문자가 동시에 저장됩니까?유닉스 읽기 및 쓰기 기능

BUFSIZ는 전송할 바이트 수입니다. BUFSIZ는 어떤 값이라도 입력에서 출력으로 복사 할 수 있다면 바이트 전송을 어떻게 제한합니까?

char buf [BUFSIZ]가 비 ASCII 문자를 저장하는 방법은 무엇입니까?

+0

비 ASCII 문자는 일반적으로 현재 UTF-8로 인코딩되므로 단일 문자는 상위 비트가 설정된 * 여러 바이트로 인코딩 될 수 있습니다. –

+0

일반적으로 BUFSIZ는 ''으로 정의되며 일반적으로 512 이상에서 2의 제곱입니다. 이 문맥에서는 1로 정의하는 것은 합법적 인 (그러나 예외적 인) 합법적 인 것입니다. 표시하는 코드는 ''또는 ''이 필요하지 않습니다. ''이면 충분합니다. –

답변

4

당신은 EOF 때까지 작은 덩어리로 읽을 왜

while ((n = read(0, buf, BUFSIZ)) > 0) 

있다고. 말 그대로 바이트 단위로 입력을 출력으로 복사합니다. 어떻게 다시 유니 코드로 변환, 콘솔의 문제가 아니라. 데이터로 심볼을 인식 할 때까지 아무 것도 출력하지 않습니다.

+0

나는 그것이 너무 많은 문자를 어떻게 읽는지 아직도 명확하지 않다. "∂ΣΣ † † ∞ ππ ~~ ∫ ∫ π χ 886661 ~ EOF"는 문자가 많고 BUFSIZ는 1 바이트 변환기 만 지정합니다. 그렇다면 어떻게 모든 것이 1 바이트의 저장 공간을 가진 배열 buf에 수용됩니까? –

+1

신중히 읽으십시오. 한 번에 1 바이트 만 가져 왔지만 필요한만큼 길게하십시오. 사과 상자가 있다고 상상해보십시오. 매우 무거워서 취급 할 수있을만큼 많이 가져가 부엌으로 옮겨 상자로 돌아갑니다. 상자가 비워 질 때까지 헹구고 반복하십시오. 따라서 처리 할 수있는 사과의 수는 버퍼 크기입니다. 그것은 조금일지도 모르지만 조만간 모든 사과를 옮길 것입니다. – KAction

+0

예를 들어, 문자'∂' (U + 2202)는 UTF-8로 3 옥텟 (바이트) :'0xe2 0x88 0x82'로 표현됩니다. 프로그램은 표준 입력에서 한 번에 하나씩 해당 바이트를 읽은 다음 한 번에 하나씩 표준 출력에 씁니다. 터미널 에뮬레이터는 3 바이트를 하나의 '∂'문자로 다시 어셈블하고 표시합니다. –

0

오류가 발생하여 '파일 끝'에 도달 할 때까지 루프를 읽으므로 각 읽기 호출 후에 buf에서 정확히 1자를 얻게됩니다. 그 문자는 write 시스템 호출을 통해 인쇄됩니다. 읽기 시스템 호출은 마지막 인수에서 지정된 것 이상 읽지 않습니다. 예를 들어 10을 전달하면 읽기가 진행되어 배열 범위를 넘어 읽은 데이터를 복사하려고 시도합니다.

먹은 문자는 확장 ASCII 문자 (코드 128-255)로 보이므로 여기서는 문제가되지 않습니다.

0

표준 입력에서 읽기를 호출하면 파이프에서 읽는 중, 터미널 또는 다른 프로그램에 바인딩됩니다. 물론 작성자 (터미널 또는 다른 프로그램)와 프로그램 사이에 버퍼가 있습니다. 이 버퍼가 언더 플로우 (underflow)되면 읽기 (프로그램)가 읽기에서 차단됩니다. 버퍼가 쓰기 차단시 writer (터미널 등)보다 오버플로 될 때

그리고 그 반대의 경우도 있습니다. 표준 출력에 파이프에 쓸 때, 터미널이나 다른 프로그램에 바인딩됩니다.

그래서 프로그램이 터미널에서 쉘에 의해 실행되면 프로그램 입력 및 출력이 (의사) 터미널에 바인딩됩니다. (Pseudo) 단말기는 사용자의 키 누름을 문자로 변환하고 인코딩 된 일부 문자열 (ISO8859-1, UTF-8 등)을 화면의 기호로 변환 할 수있는 프로그램입니다.

  1. 문자는 EOL의 EOF를 누르기 전에 터미널 프로그램에 저장됩니다. 이것이 단말기의 표준 모드입니다. 누르기를 입력하면 바이트가 프로그램에 바인드 된 파이프에 기록됩니다.
  2. BUFSIZ는 한 번의 작업 당 입력에서 읽으려고하는 바이트 수입니다. n 반환 값은 작업이 완료 될 때 실제로 읽은 바이트 수입니다. 따라서 BUFSIZ는 프로그램에서 파이프에서 읽을 수있는 최대 바이트입니다.
  3. char [BUFSIZ]는 바이트 배열 (일부 charset 문자가 아님)이므로 모든 값 (인쇄 할 수없고 0 포함)을 처리 할 수 ​​있습니다.