cst디오 스트림 vs ios 스트림 스트림 스트림?
의 .ios_base::sync_with_stdio- ,이면)다 할 수 .iostream 및 C++및 C+에서cstdio표준 C의 일부인 스트림.
생각했어요stdout,stderr그리고.stdinC에서 기본적으로 iostreams 클래스에서 C++의 객체 집합으로 랩핑되었습니다.하지만 만약 그들이 서로 동기화되어야 한다면, 이것은 C++의 것을 의미할 것입니다.iostream클래스는 C의 주위에 포장지가 아닙니다.stdin타.
제가 이거 때문에 좀 혼란스러운데요?C++의 ios 스트림과 C의 stdio가 어떻게 추상화 수준이 다를 뿐 아니라 정확히 같은 일을 하는 다른 것인지 누가 설명해 줄 수 있습니까?저는 그들이 똑같은 줄 알았어요!?
어떻게 그들이 동기화되어야 합니까?저는 항상 그것들이 같은 것이고, 하나는 다른 것을 싸고, 본질적으로 같은 것이라고 생각했습니다.
C 및 C++ 표준은 특정 작업의 효과가 무엇인지에 대한 것일 뿐, 구현 방식에 대한 요구 사항을 지정하지 않습니다.은.<stdio>대<iostream>이것은 한 쪽이 다른 쪽을 감쌀 수 있고, 둘 다 본질적으로 동일할 수 있거나, 완전히 독립적일 수 있다는 것을 의미합니다.은 여러 로 이상적일 : 으로,다예:입니다)을 확장하는 입니다).FILE*(사용자 정의 시스템의 경우) 하지만 실제로 이러한 작업을 수행하는 시스템은 알지 못합니다. 것은 입니다를 하는 것입니다.<iostream><stdio>특정 작업에 추가 비용이 발생하고 대부분의 C++ 표준 라이브러리가 완전히 별개의 구현을 사용하도록 전환했다는 단점이 있지만 일반적인 구현 방식이었습니다.
불행하게도 랩핑과 독립적인 구현 모두 공통적인 문제를 가지고 있습니다.한 문자 수준을 수행하면 I/O가 극도로 비효율적입니다.따라서 문자를 버퍼링하고 버퍼에서 읽거나 버퍼에 쓰는 것이 필수입니다.이것은 서로 독립적인 스트림에 적합합니다. C 준 C입니다입니다.stdin,stdout,stderr 그들의 은 C++물을의합니다.std::cin,std::cout,std::cerr/std::clog C 문자 및 C++std::wcin,std::wcout,std::wcerr/std::wclog가 두 를 모두 때 하는 동작, :stdin그리고.std::cin 중 가 기본 표시됩니다 이러한 스트림 중 하나가 기본 OS 스트림에서 문자 버퍼를 읽어오면 읽기가 순서에 맞지 않게 표시됩니다. 둘 다로일 ,stdout그리고.std::cout사용된 독립 버퍼 문자는 사용자가 두 스트림에 모두 쓸 때 예기치 않은 순서로 나타납니다. C준 C++체즉을 들어, C++체))다에 이 존재합니다.std::cin,std::cout,std::cerr,그리고.std::clog은 이 각각의물과 합니다.합니다.<stdio>상대편의 이는 C가 공통 을 직접 하거나 효과적으로적인 C++ 객체들이 직접적으로 공통 구현을 사용하거나 다음과 같은 측면에서 구현된다는 것을 의미합니다를 이는 구체적으로 이러한합니다.<stdio> 그리고 어떤 문자도 버퍼링하지 마세요.
가 만 할 수 경우 을 알 수 있었습니다.<iostream>그는 추가적인 간접 비용을 지불하고 싶지 않으며, 더 중요한 것은 버퍼를 사용하지 않음으로써 발생하는 추가 비용을 지불하고 싶지 않다는 것입니다.신중한 구현을 위해서는 버퍼를 사용하지 않는 비용이 상당히 클 수 있습니다. 이는 특정 작업이 한 번씩만 수행하는 것이 아니라 각 반복 작업에서 가상 함수 호출을 수행해야 한다는 것을 의미하기 때문입니다.따라서,std::sync_with_stdio()이 동기화를 끄는 데 사용할 수 있습니다. 이는 표준 스트림 개체가 내부 구현을 다소 완전히 변경함을 의미할 수 있습니다.표준 스트림 개체의 스트림 버퍼는 사용자가 교체할 수 있으므로 안타깝게도 스트림 버퍼는 교체할 수 없지만 스트림 버퍼의 내부 구현은 변경할 수 있습니다.
을 잘 <iostream>라이브러리 이 모든 것은 표준 스트림 개체에만 영향을 미칩니다.은 이에 영향을 받지 않아야 .즉,다.표준 합니다를 않을입니다.<stdio>그리고.<iostream>동기화를 꺼야 합니다. I 성능 시I/Oo<stdio>그리고.<iostream>당신은 이것을 알아야 합니다.
은.stdout,stderr그리고.stdinOS의 파일 핸들러입니다. 그리고.FILE 뿐만 C라 C의의 iostreamC++ 클래스는 모두 해당 파일 처리기의 래퍼입니다. 또는 이 올바르게 이 있을 수 iosstream와 FILE다.
좋아요, 제가 찾은 것은 이렇습니다.
실제로 I/O는 궁극적으로 네이티브 시스템 호출 및 기능에 의해 수행됩니다.
이제 Microsoft Windows를 예로 들어 보겠습니다.다에 .STDIN,STDIO등(여기 참조).그래서 기본적으로 C++ 둘 다iostream C.stdio수, C++iostream는 (현대적인 구현에서는) C의 I/O 기능을 랩핑하지 않습니다.네이티브 시스템 메소드를 직접 호출합니다.
그리고 이것을 발견했습니다.
stdin, stdout 및 stderr이 리디렉션되면 printf() 및 gets()와 같은 표준 C 기능을 변경 없이 사용하여 Win32 콘솔과 통신할 수 있습니다.하지만 C++ I/O 스트림은 어떻습니까?Cin, cout, cerr, clock은 C의 stdin, stdout, stderr와 밀접한 관련이 있으므로, 이들이 유사한 행동을 할 것으로 예상할 수 있습니다.이거 반만 맞아요.
C++ I/O 스트림은 템플릿과 템플릿이 아닌 두 가지 맛으로 제공됩니다.I/O 스트림의 이전 비템플릿 버전은 STL(Standard Template Library)에 의해 처음 정의되어 현재 ANSI C++ 표준으로 흡수되고 있는 새로운 템플릿 스타일의 스트림으로 서서히 대체되고 있습니다.Visual C++ v5는 두 가지 유형을 모두 제공하며 서로 다른 헤더 파일을 포함하여 둘 중 하나를 선택할 수 있습니다.STL I/O 스트림은 새로 리디렉션된 stdio 핸들을 자동으로 사용하여 예상한 대로 작동합니다.그러나 템플릿이 아닌 I/O 스트림은 예상대로 작동하지 않습니다.그 이유를 알아보기 위해 Visual C++ CD-ROM에서 편리하게 제공되는 소스 코드를 살펴 보았습니다.
문제는 오래된 I/O 스트림이 핸들 대신 정수가 사용되는 UNIX 스타일의 "파일 디스크립터"를 사용하도록 설계되었다는 것입니다(stdin의 경우 0, stdout의 경우 1 등).이는 UNIX 구현에서는 편리하지만 Win32 C 컴파일러는 호환되는 기능 집합을 제공하지 않기 때문에 해당 스타일의 I/O를 나타내기 위해 또 다른 I/O 계층을 제공해야 합니다.어쨌든 _open_osfhandle()을 호출하여 새 Win32 핸들을 (예를 들어) stdout에 연결하면 I/O 코드의 다른 계층에 영향을 미치지 않습니다.따라서 파일 디스크립터 1은 이전과 동일한 기본 Win32 핸들을 계속 사용할 것이며 출력을 cout으로 전송해도 원하는 효과를 얻지 못할 것입니다.
다행히도, 원래의 I/O 스트림 패키지의 설계자들은 이 문제를 예견하고 깨끗하고 유용한 솔루션을 제공했습니다.기본 클래스 ios는 라이브러리가 표준 I/O 계층의 변경 사항을 반영하도록 기본 파일 설명자를 변경하도록 하는 정적 함수 sync_with_stdio()를 제공합니다.STL I/O 스트림에 엄격하게 필요한 것은 아니지만 해가 되지 않으며 새 형식 또는 이전 형식의 I/O 스트림에서 올바르게 작동하는 코드를 작성할 수 있습니다.
(출처)
sync_with_stdio()기본 파일 설명자를 실제로 변경합니다.실제로 설계자들은 이전 C++ I/O가 정수 대신 핸들을 사용하는 Windows-32와 같은 시스템과 호환되도록 하기 위해 추가했습니다.
sync_with_stdio()현대 C++ 템플릿 기반 STLI I/O에는 필요 없습니다.
같은 것이지만 따로 버퍼링을 할 수도 있습니다.이는 C와 C++ I/O의 사용을 혼합하는 코드에 영향을 줄 수 있습니다.
std::cout << "Hello ";
printf("%s", "world");
std::cout << "!\n";
이 작업을 수행하려면 기본 스트림이 어떻게든 동기화되어야 합니다.일부 시스템에서는 성능이 저하될 수 있습니다.
그래서, 표준은 당신이 전화할 수 있게 해줍니다.std::sync_with_stdio(false)이와 같은 코드는 신경 쓰지 않지만, 차이가 있다면 표준 스트림이 가능한 한 빨리 작동하도록 하고 싶다고 말하는 것입니다.많은 시스템에서는 차이가 없습니다.
하나는 다른 하나의 포장지가 될 수 있습니다. (그리고 그것은 양쪽 모두 효과가 있습니다.)구현할 수 있습니다.stdio를 를 설정합니다.iostream그리고 역도 성립.아니면 완전히 독립적으로 작성할 수도 있습니다.
그리고.sync_with_stdio활성화되어 있으면 두 스트림이 동기화됩니다.하지만 이 기능이 비활성화되어 있는 경우에도 동기화할 수 있습니다.
그러나 한 개가 다른 하나의 포장지일지라도, 예를 들어 다른 하나가 공유하지 않는 버퍼를 여전히 가지고 있을 수 있으므로 동기화가 여전히 필요합니다.
언급URL : https://stackoverflow.com/questions/9653751/cstdio-streams-vs-iostream-streams
'programing' 카테고리의 다른 글
| PowerShell의 Format-List에서 출력을 문자열로 가져오려면 어떻게 해야 합니까? (0) | 2023.09.21 |
|---|---|
| 게시물의 최상위 카테고리를 얻기 위한 워드프레스 기능? (0) | 2023.09.21 |
| Windows에서 Rust에서 MariaDBC Connector로의 링크가 실패함 (0) | 2023.09.21 |
| SQL: null로 설정된_number로 변환할 수 없는 경우 (0) | 2023.09.21 |
| 오라클 데이터베이스가 명령 프롬프트를 통해 .sql 파일 가져오기 (0) | 2023.09.21 |