2014-11-21 3 views
0

문자열로 :: istream로를 문자열로 :는 표준 데이터의 고정 길이를 복사 :: istream로를 내가 표준 데이터의 고정 된 길이를 복사 할

std::istream & operator >> (std::istream & is, LogMsg & msg) 
{ 
    // read in 4 bytes - a uint32_t that describes the number of bytes in message: 
    // next, read the message bytes into the LogMsg 

    typedef std::istream_iterator<unsigned char> Iter; 

    Iter   i (is); 
    uint32_t  nSize = 0; 
    std::string & sMsg = msg.MsgRef(); 

    is >> nSize; 
    sMsg.reserve(nSize); 

    std::copy(
     i.begin(), i.begin() + nSize, 
     std::back_inserter(sMsg) 
    ); 

    return is; 
} 

난 못해 iterator의 std :: istream_iterator :: begin() 함수는 C++ 11에서만 사용할 수 있습니다 (gcc를 사용하여 -std = gnu ++ 0x로 제한됨). 4.4.7

고정 된 길이의 데이터를 입력 스트림에서 문자열로 복사 할 수 있습니까?

원래 std :: istream :: read에서 loooked되었습니다. llowing 구문

is.read (buffer,length); 

하지만 난 당신이 문자열의 내부 버퍼로 읽을 수있는 내가 임시 버퍼에 복사를하지 않으려는 생각하지 않습니다. 어떻게 든 streambuf를 사용할 수 있습니까?

+0

AFAIK C++ 11에서'istream_iterator'를위한'begin()'/'end()'함수는 없습니다. – 0x499602D2

+0

스트림은 컨테이너가 아닌 _ 데이터 _ 흐름입니다. –

답변

3

확실한 해결책은 std::copy_n입니다 : 당신은 문자가 확신 할 수있는 경우

std::copy_n(std::istreambuf_iterator<char>(is), size, std::back_inserter(msg)); 

이는 그러나, 작동합니다. 문자를 읽는 동안 파일 끝을 발견하면 정의되지 않은 동작이 계속됩니다. 즉, 그것이 명백한 해결책이지만, 그것은 아마도 좋은 것이 아닙니다.

그러나 C++ 11에서는 공식적으로 이전 구현에서 연습에서 내부 버퍼를 읽을 수 있습니다. C++ 11에서 기본 연속성의 보장에도 불구하고,

msg.resize(size); 
is.read(&msg[0], msg.size()); 

은 (어떤 이유로, std::string::data()의 const가 아닌 버전이되지 않습니다 : 당신은 문자열 충분한 공간이 있는지 확인 을해야합니다.)

3
당신은 문자열의 내부 버퍼에 복사 할 수 있습니다

, 그냥 적당한 크기의 확인 : 당신이 갖고 있기 때문에

sMsg.resize(nSize); 
is.read(&sMsg[0], nSize); 

그것은 begin()와 솔루션을보다 효율적 데이터의 전체 무리를 제로 초기화 당신을 즉시 덮어 씁니다. 그러나 pre-C++ 11에서 작동합니다.

+0

기술적으로 UB pre-C++ 11입니다. –

+0

'sMsg [0]'으로 읽어 들인가요? 어째서? – Barry

+0

연속성은 엄격히 보장되지 않습니다. 실제로 그것의 _sort_이었다. 실제로 GCC 4.9에서 C++ 11에서는 호환되지 않는 COW와 함께 이전 구현을 사용하고 있다고 생각합니다. 이야기의 도덕은 직접 문자열 액세스에 매우주의해야합니다. –

3

사용 std::copy_n() :

std::copy_n(i, nSize, std::back_inserter(sMsg)); 
+0

'n '문자를 읽기 전에 파일 끝을 발견하면 정의되지 않은 동작이 발생하고 오류는 발생하지 않습니다. –

+0

@JamesKanze 왜 그렇습니까? – 0x499602D2

+0

표준에서 그렇게 말하기 때문입니다. 왜 그런지, 나는 모른다. 필자는 저자가 특별히 지정하고 싶지 않은 경우라고 생각합니다. –