수색…


비고

std::istream_iterator 의 디폴트의 constructor은, 스트림의 마지막을 나타내는 반복자를 구축합니다. 따라서 std::copy(std::istream_iterator<int>(ifs), std::istream_iterator<int>(), ....ifs 의 현재 위치에서 끝까지 복사하는 것을 의미합니다.

문자열 스트림

std::ostringstream 은 객체가 출력 스트림처럼 보이는 클래스입니다 (즉, operator<< 를 통해 객체에 쓸 수 있지만 실제로 쓰기 결과를 저장하고 스트림 형식으로 제공합니다).

다음 단축 코드를 고려하십시오.

#include <sstream>
#include <string>                                                                                                                          

using namespace std;

int main()
{
    ostringstream ss;
    ss << "the answer to everything is " << 42;
    const string result = ss.str(); 
}   

라인

ostringstream ss;

그러한 객체를 만듭니다. 이 객체는 먼저 일반 스트림과 같이 조작됩니다.

ss << "the answer to everything is " << 42;

그 다음에, 결과 스트림은 다음과 같이 얻을 수 있습니다.

const string result = ss.str();

(문자열 result"the answer to everything is 42" ).

이는 주로 스트림 직렬화가 정의되어 있고 문자열 형식이 필요한 클래스가있는 경우에 유용합니다. 예를 들어, 어떤 클래스가 있다고 가정합니다.

class foo 
{   
    // All sort of stuff here.
};  

ostream &operator<<(ostream &os, const foo &f);

foo 객체의 문자열 표현을 얻으려면,

foo f;

우리는

ostringstream ss; 
ss << f;
const string result = ss.str();        

그런 다음 result 에는 foo 객체의 문자열 표현이 포함됩니다.

끝까지 파일 읽기

텍스트 파일을 한 줄씩 읽음

ifstream 문서에서 텍스트 파일을 한 줄씩 끝까지 읽는 적절한 방법은 일반적으로 명확하지 않습니다. 초보자 C ++ 프로그래머가 자주 범하는 실수와 파일을 읽는 적절한 방법을 생각해 보겠습니다.

공백 문자가없는 행

간단히하기 위해 파일의 각 줄에 공백 기호가 없다고 가정 해 봅시다.

ifstream 에는 스트림에 오류가없고 읽을 준비가되었을 때 true를 반환하는 operator bool() 이 있습니다. 게다가, ifstream::operator >> 는 스트림 자체에 대한 참조를 리턴하므로 매우 우아한 구문으로 한 행에서 EOF (오류는 물론 오류)를 읽고 확인할 수 있습니다.

std::ifstream ifs("1.txt");
std::string s;
while(ifs >> s) {
    std::cout << s << std::endl;
}

공백 문자가있는 행

ifstream::operator >> 는 공백 문자가 발생할 때까지 스트림을 읽습니다. 따라서 위의 코드는 한 줄의 단어를 별도의 줄에 인쇄합니다. 줄 끝까지 모든 것을 읽으려면 ifstream::operator >> 대신 std::getline 사용하십시오. getline 은 작업 한 스레드에 대한 참조를 반환하므로 동일한 구문을 사용할 수 있습니다.

while(std::getline(ifs, s)) {
    std::cout << s << std::endl;
}

분명히 std::getline 은 끝까지 단일 행 파일을 읽는 데에도 사용해야합니다.

한 번에 버퍼로 파일 읽기

마지막으로 공백 문자와 개행 문자를 포함하여 모든 문자에서 멈추지 않고 처음부터 끝까지 파일을 읽으십시오. 정확한 파일 크기 또는 길이의 상한이 허용되는 경우 문자열의 크기를 조정 한 다음 읽을 수 있습니다.

s.resize(100);
std::copy(std::istreambuf_iterator<char>(ifs), std::istreambuf_iterator<char>(),
    s.begin());

그렇지 않으면, 우리는 문자열의 끝에 각 문자를 삽입해야하므로 std::back_inserter 가 필요합니다.

std::copy(std::istreambuf_iterator<char>(ifs), std::istreambuf_iterator<char>(),
    std::back_inserter(s));

또는 iterator 범위 인수가있는 생성자를 사용하여 스트림 데이터로 컬렉션을 초기화 할 수 있습니다.

std::vector v(std::istreambuf_iterator<char>(ifs),
    std::istreambuf_iterator<char>());

다음 예제는 ifs 가 바이너리 파일로 열리는 경우에도 적용됩니다.

std::ifstream ifs("1.txt", std::ios::binary);

스트림 복사 중

스트림과 반복자가있는 파일을 다른 파일에 복사 할 수 있습니다.

std::ofstream ofs("out.file");
std::copy(std::istreambuf_iterator<char>(ifs), std::istreambuf_iterator<char>(),
    std::ostream_iterator<char>(ofs));
ofs.close();

또는 호환 가능한 인터페이스로 다른 유형의 스트림으로 재 지정됩니다. 예를 들어 Boost.Asio 네트워크 스트림 :

boost::asio::ip::tcp::iostream stream;
stream.connect("example.com", "http");
std::copy(std::istreambuf_iterator<char>(ifs), std::istreambuf_iterator<char>(),
    std::ostream_iterator<char>(stream));
stream.close();

배열

반복자는 포인터의 일반화로 생각할 수 있으므로 위 예제의 STL 컨테이너는 기본 배열로 대체 될 수 있습니다. 숫자를 배열로 파싱하는 방법은 다음과 같습니다.

int arr[100];
std::copy(std::istream_iterator<char>(ifs), std::istream_iterator<char>(), arr);

배열을 할당 한 후에는 배열의 크기를 변경할 수 없으므로 버퍼 오버플로에주의하십시오. 예를 들어 위의 코드에 100 개 이상의 정수가 포함 된 파일이 제공되면 배열 외부에 쓰고 정의되지 않은 동작으로 실행하려고 시도합니다.

iostream으로 컬렉션 인쇄하기

기본 인쇄

std::ostream_iterator 사용하면 STL 컨테이너의 내용을 명시 적 루프가없는 출력 스트림에 인쇄 할 수 있습니다. std::ostream_iterator 생성자의 두 번째 인수는 구분 기호를 설정합니다. 예를 들어 다음 코드가 있습니다.

std::vector<int> v = {1,2,3,4};
std::copy(v.begin(), v.end(), std::ostream_iterator<int>(std::cout, " ! "));

인쇄 할 것이다.

1 ! 2 ! 3 ! 4 !

암시 적 형식 캐스트

std::ostream_iterator 사용하면 컨테이너의 내용 유형을 암시 적으로 캐스트 할 수 있습니다. 예를 들어, 소수점 이하 3 자리수의 부동 소수점 값을 출력하기 위해 std::cout 을 조정 해보자.

std::cout << std::setprecision(3);
std::fixed(std::cout);

포함 된 값이 int 채로 std::ostream_iteratorfloat 인스턴스화합니다.

std::vector<int> v = {1,2,3,4};
std::copy(v.begin(), v.end(), std::ostream_iterator<float>(std::cout, " ! "));

그래서 위의 코드는 yield

1.000 ! 2.000 ! 3.000 ! 4.000 !

std::vector 에도 불구하고 int 는 보유하고있다.

생성 및 변환

std::generate , std::generate_nstd::transform 함수는 즉석 데이터 조작을위한 매우 강력한 도구를 제공합니다. 예를 들어 벡터가있는 경우 :

std::vector<int> v = {1,2,3,4,8,16};

우리는 각 요소에 대해 "x is even"문을 부울 값으로 쉽게 인쇄 할 수 있습니다.

std::boolalpha(std::cout); // print booleans alphabetically
std::transform(v.begin(), v.end(), std::ostream_iterator<bool>(std::cout, " "),
[](int val) {
    return (val % 2) == 0;
});

또는 제곱 된 요소를 인쇄하십시오.

std::transform(v.begin(), v.end(), std::ostream_iterator<int>(std::cout, " "),
[](int val) {
    return val * val;
});

N 개의 공백으로 구분 된 난수 인쇄 :

const int N = 10;
std::generate_n(std::ostream_iterator<int>(std::cout, " "), N, std::rand);

배열

텍스트 파일을 읽는 방법에 대한 섹션에서와 같이, 이러한 모든 고려 사항은 원시 배열에 적용될 수 있습니다. 예를 들어, 네이티브 배열에서 제곱 된 값을 출력합시다.

int v[] = {1,2,3,4,8,16};
std::transform(v, std::end(v), std::ostream_iterator<int>(std::cout, " "),
[](int val) {
    return val * val;
});

파일 구문 분석

파일을 STL 컨테이너로 파싱하기

istream_iterator 는 코드에서 명시적인 루프없이 STL 컨테이너에 숫자 또는 다른 구문 분석 가능한 데이터 시퀀스를 읽는 데 매우 유용합니다.

명시 적 컨테이너 크기 사용 :

std::vector<int> v(100);
std::copy(std::istream_iterator<int>(ifs), std::istream_iterator<int>(),
    v.begin());

또는 iterator를 삽입하여 :

std::vector<int> v;
std::copy(std::istream_iterator<int>(ifs), std::istream_iterator<int>(),
    std::back_inserter(v));

입력 파일의 숫자는 임의의 개수의 공백 문자와 개행으로 나눌 수 있습니다.

이기종 텍스트 테이블 구문 분석

istream::operator>> 는 공백 기호까지 텍스트를 읽으므로 복잡한 조건에서 while 데이터를 사용하여 복잡한 데이터 테이블을 구문 분석 할 수 있습니다. 예를 들어, 두 개의 실수가있는 파일과 각 행에 공백이없는 파일이있는 경우 :

1.12 3.14 foo
2.1 2.2 barr

다음과 같이 파싱 될 수 있습니다.

std::string s;
double a, b;
while(ifs >> a >> b >> s) {
    std::cout << a << " " << b << " " << s << std::endl;
}

변환

모든 range-manipulating 함수는 std::istream_iterator 범위와 함께 사용될 수 있습니다. 그 중 하나는 std::transform , 즉석에서 데이터를 처리 할 수 ​​있습니다. 예를 들어 정수 값을 읽고 3.14를 곱한 다음 결과를 부동 소수점 컨테이너에 저장합니다.

std::vector<double> v(100);
std::transform(std::istream_iterator<int>(ifs), std::istream_iterator<int>(),
v.begin(),
[](int val) {
    return val * 3.14;
});


Modified text is an extract of the original Stack Overflow Documentation
아래 라이선스 CC BY-SA 3.0
와 제휴하지 않음 Stack Overflow