파일의 마지막 문자는 무엇입니까?


19

방금 "파일 끝에서 줄 바꿈 문자 제거"에 대한 답변을 읽었으며 모든 사람이 마지막 문자를 삭제하라고 말했습니다. 내 질문은, eof 캐릭터가 마지막 캐릭터가 아닌가?



1
@SorenBjornstad 또한 Unix 텍스트 파일 끝에 줄 바꿈이 있으면 마지막 줄이 끝나기 때문에 거기에 있다고 덧붙이고 싶습니다. 빈 텍스트 파일의 끝에는 줄 바꿈이 없습니다. 일련의 0 자입니다.
Kaz

3
CPM과 DOS는 약간 놀랍게도 ^ Z를 EOF 문자로 사용했지만 ^ Z로 끝나는 파일이 여전히 나타날 수 있습니다.
Edward Falk

답변:


13

이전 응답의 상태가 올바르므로 파일이 파일 끝 문자로 끝나지 않습니다. 그러나 답변과 의견에는 지적 할 가치가있는 부정확성이 포함되어 있다고 생각합니다.

  • ASCII 문자 세트에는 정확한 EOF 문자가 포함되어 있지 않습니다. 텍스트 끝 (3), 전송 끝 (4), 전송 끝 블록 (23), 매체 끝 (25)과 같은 여러 "종료"제어 문자가 있습니다. 파일 구분 기호 (28)는 EOF 문자에 가장 가깝습니다. 코드 26은 EOF가 아닌 "대체"입니다.

  • Ctrl- D터미널 입력에만 연결됩니다. 예를 cat filea fileb filec > outfile들어이 명령 에는 Ctrl- 가 포함되지 않습니다 D. 그건 그렇고, 당신보다 뭔가 다른 터미널 EOF 문자를 변경할 수 있습니다 Ctrl- D사용하여 stty명령을.

  • 엄밀히 말해서 Ctrl- D(또는 변경 한 것)은 EOF 키 코드가 아닙니다. 그것이하는 것은 readreturn을 누르면 시스템 호출이 호출자에게 한 줄의 문자를 리턴하는 것처럼 시스템 호출을 입력이 가능한 상태로 리턴하는 것입니다. 통상적 으로, 판독 시스템 호출 (즉, 제로 문자 판독)로부터의 리턴 값 0은 파일의 종료 조건을 신호한다. 그러나 입력 파일은 자동으로 닫히지 않으며 입력이 터미널에서 오는 경우 "파일 끝"상태가되지 않습니다. "파일 끝"이후에도 터미널에서 계속 읽는 프로그램을 작성할 수 있으며 읽기 호출은 다음 입력 행에 대해 0이 아닌 값을 리턴 할 수 있습니다.

  • eof 문자와 eol 문자의 유추는 일부 입력이 이미 행에 쓰여져있을 때 Ctrl- D를 누르면 볼 수 있습니다 . 예를 들어, "ABC"와 언론 작성하는 경우 Ctrl- D읽기 호출이 반환, 3 및 인수로 전달 된 버퍼에 저장 "ABC"와 반환 값이 시간을. read는 0을 반환하지 않으므로 위의 규칙에 따라 EOF 조건으로 해석되지 않습니다. 마찬가지로 Return 키를 누르면 전체 입력 행 (줄 바꿈 포함)과 함께 읽기 호출이 반환됩니다. 이 cat명령 을 사용하여 시도해 볼 수 있습니다 . 행에 일부 문자를 쓰고 Ctrl-를 누르십시오 D. 문자가 다시 에코되고 cat더 많은 입력을 기다리는 것을 볼 수 있습니다.

  • 위의 모든 내용은 라인 입력 처리가 최소화되는 "raw"모드와 달리 터미널이 "cooked"모드 인 경우에만 적용됩니다. 원시 모드에서 Ctrl-D 문자는 실제로 입력 버퍼로 전달됩니다.


19

ASCII 제어 문자에는 1960 년대의 정의가 있습니다 (실제로 네트워크를 고려할 수있는 것보다 앞서 있습니다 ). 이러한 제어 문자가 모두 통신 장비에 대해 정의 된 방식으로 사용되는 것은 아닙니다.

유닉스 계열 시스템에서는 EOF캐릭터 가 필요하지 않습니다 . 사용되지 않습니다. 시스템은 파일에 몇 바이트가 있는지 응용 프로그램에 알려줄 수 있습니다.

  • VMS, DOS, Windows에서 볼 수있는 일부 다른 시스템에서는 control-Z가 파일 끝 표식으로 작동 할 수 있습니다. 이전 버전에서는 시스템이 일부 응용 프로그램에 파일에 몇 바이트가 있는지 알 수 없었기 때문입니다 .

    VMS의 경우 제한은 C 런타임이 작동하는 방식 때문이었습니다. 어셈블리 언어 응용 프로그램은 올바른 파일 크기를 얻을 수있었습니다.

  • 쉘의 유닉스 시스템은 일반적으로 control-D를 사용하여 입력 끝 (파일)에 도달했지만 control-D는 파일에 저장되지 않았다는 것을 응용 프로그램에 알립니다.

C에서는 EOF의도적으로 -1유효한 문자가 아님을 나타 내기 위해 만들어졌습니다 . EOF파일 끝 조건이 감지되면 특수 문자가 아닌 표준 I / O가 반환 됩니다.

그건 그렇고, 파일은 개행 (ASCII 줄 바꿈) 문자로 끝나지 않아도 됩니다. 텍스트 편집기는 모두 인쇄 가능한 텍스트이지만 후행 줄 바꿈이없는 파일을 처리 할 수 ​​있습니다.


8
POSIX는 텍스트 파일을 일련의 줄을 포함하는 파일로 정의 하고 각 줄을 줄 바꿈이 아닌 문자 순서와 한 줄 바꿈으로 차례로 정의합니다. 따라서 0x0A 이외의 것으로 끝나는 파일은 적합한 텍스트 파일이 아닙니다.
Damian Yerrick 22:07에

2
나는 그것을 알고 있습니다. 그래서 텍스트 편집기가 작동 한다고 지적했습니다 . 이진 파일에는 그러한 제약이 없습니다.
Thomas Dickey

적어도 줄 바꿈이없는 텍스트로 처리되도록 의도 된 파일은 여전히 ​​실제로 원한다면 적어도 전형적인 텍스트 편집기가 그러한 파일을 보완하도록 코딩 된 경우에도 여전히 나쁜 형식이라는 점에 주목할 가치가 있습니다. 광범위하게 사용자 친화적 인 / 호환, 뒤에 줄 바꿈의 부족 (/ 합치 여러 텍스트 파일을 인쇄, 일반 명령 줄 도구와 같은 최소한의 편집자로 구문 분석 다양한 상황에서 추가적인 어려움을 추가 할 수 있기 때문에 busyboxS ' vi등).
mtraceur

(1) VMS 이전에 RT-11 RSX-11 TOPS-10은 파일 시스템을 블록 단위로만 정밀하게 만들었으며 EOF 문자가 필요했습니다. CP / M도 DEC에서 복사하여 초기 MS-DOS에서 복사 한 다음 Windows로 전달했습니다. (2) 유닉스에서는 사람들이 일반적 으로 tty 장치에서 쉘을 실행 하지만 JohanM이 자세히 설명하는 것처럼 쉘이 아닌 tty 드라이버 입니다.
dave_thompson_085

물론-DEC가 돌아 왔습니다 ( 이전 버전을 언급했음을 참고하십시오 ). CP / M 기능 의 원천 인지 여부 는 흥미로운 주제입니다 (여기서는 안됨). 대안에 대한 배경 지식을 제공하기 위해 이러한 사례를 언급했습니다.
Thomas Dickey

7

EOF는 문자가 아닙니다. 파일 스트림에서 읽을 문자가 더 이상 없음을 나타내는 상태입니다. 터미널에서 EOF 명령을 입력하면 특수 문자를 입력하지 않고 OS에 입력 스트림을 닫으라고 신호합니다.


1
예. 그러나 ASCII 테이블에서 EOF는 26이므로 마지막 바이트는 26의 이진 표현이라고 생각했습니다. 그러면 입력을 읽는 프로그램이 어떻게 끝나는 지 알 수 있습니까?
sworwitz

ASCII는 네트워크를 통해 정보를 전달하기위한 것입니다. 이 경우 EOF 문자가 필요합니다. (ASCII에는 많은 제어 코드가 있습니다. 모든 것이 인쇄 가능한 것은 아닙니다.) 파일 스트림의 경우 파일 크기는 파일 시스템을 통해 이미 알려져 있으므로 OS에서 읽을 데이터가 더 이상 없을 때 알 수 있습니다.
Munir

@sworwitz : C와 관련하여 호출 당 문자를 반환하는 입력 읽기 기능은 문자가 아닌 int (일반적으로 32 비트 숫자이지만 최소 16 비트 여야 함)를 반환합니다. 함수 신호와 EOF는 유효한 8 비트 값이 아닌 -1 (0xffffffff)을 반환하여 0xff가 아닌 ASCII 문자와 혼동되지 않습니다. 문자열을 반환하는 함수는 읽은 데이터의 길이도 반환합니다. 이 길이는 데이터가 없거나 데이터 끝을 알리는 데 사용될 수 있습니다 (길이는 -1 일 수 있음). 마지막으로, 스트림이 끝났는지 알려주는 함수도 있습니다
slebetman

알았어 고마워! bash에서 Ctrl + d를 누르면 ASCII 문자를 입력합니다.
sworwitz

@sworwitz 정확하지 않습니다. 입력을 받기 전에 bashTTY 드라이버가 마사지를받습니다. 이 드라이버는 Ctrl-D를 가로 채서 EOF를 보냅니다 bash (EOF가 문자가 아니라 특수 파일 상태 인 경우)
Stig Hemmer
당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.