문제

어쨌든 임시 버퍼를 만들지 않고 알려진 바이트를 std :: 문자열에 직접 읽을 수 있습니까?

예를 들어 현재 할 수 있습니다

boost::uint16_t len;
is.read((char*)&len, 2);
char *tmpStr = new char[len];
is.read(tmpStr, len);
std::string str(tmpStr, len);
delete[] tmpStr;
도움이 되었습니까?

해결책

std::string a resize 사용할 수있는 기능 또는 동일한 작업을 수행하는 생성자.

boost::uint16_t len;
is.read((char*)&len, 2);

std::string str(len, '\0');
is.read(&str[0], len);

이것은 테스트되지 않았으며 문자열이 인접한 저장 공간을 갖도록 의무화되어 있는지 모르겠습니다.

다른 팁

copy_n과 insert_iterator의 조합을 사용할 수 있습니다.

void test_1816319()
{
    static char const* fname = "test_1816319.bin";
    std::ofstream ofs(fname, std::ios::binary);
    ofs.write("\x2\x0", 2);
    ofs.write("ab", 2);
    ofs.close();

    std::ifstream ifs(fname, std::ios::binary);
    std::string s;
    size_t n = 0;
    ifs.read((char*)&n, 2);
    std::istream_iterator<char> isi(ifs), isiend;
    std::copy_n(isi, n, std::insert_iterator<std::string>(s, s.begin()));
    ifs.close();
    _unlink(fname);

    std::cout << s << std::endl;
}

복사, 해킹 없음, 오버런 가능성 없음, 정의되지 않은 동작.

Getline과 같은 것을 사용할 수 있습니다.

#include <iostream>
#include <string>
using namespace std;

int main () {
  string str;
  getline (cin,str,' ');
}

벡터를 버퍼로 사용합니다.

boost::uint16_t len;
is.read((char*)&len, 2); // Note if this file was saved from a different architecture 
                         // then endianness of these two bytes may be reversed.

std::vector buffer(len);  // uninitialized.
is.read(&buffer[0], len);

std::string  str(buffer.begin(),buffer.end());

비록 당신은 아마도 문자열을 버퍼로 사용하여 도망 갈 것입니다 (GMAN에서 설명한대로). Strings 멤버가 연속 위치에 있다는 것은 표준에 의해 보장되지 않습니다 (따라서 현재 구현을 확인하고 다른 컴파일러/플랫폼으로 포팅 할 때 확인해야한다는 큰 의견을 제시하십시오).

코드 길이를 최적화하거나 여기에서 사본을 저장하려고합니까? 임시 버퍼에 무슨 문제가 있습니까?

나는 당신이 실제로 문자열의 보호를 우회하고 있다고 주장합니다. 사본의 성능이 STD :: 문자열에 대한 성능이 걱정된다면 응용 프로그램의 성능에 영향을 미치는 방식이라는 것을 식별했기 때문에 Char*와 직접 작업 할 것입니다.

편집 : 더 많은 외모를 ...사본없이 char*에서 std :: 문자열 초기화

두 번째 대답에서, 당신은 당신이 달성하고자하는 것을 달성 할 수 없다고 꽤 평평하게 언급되어 있습니다 (즉, CHAR* 위에 반복하지 않고 STD :: 문자열을 채우십시오.)

로드 루틴을 살펴보고 (여기에 게시 할 수 있습니까?) 할당을 최소화하십시오 : 새롭고 삭제는 확실히 무료가 아니므로 버퍼를 지속적으로 재창조 할 필요가 없다면 최소한 시간을 절약 할 수 있습니다. 나는 항상 버퍼를 0으로 memseting으로 지우거나 각 반복 각 배열의 첫 번째 인덱스를 종료하여 널로 지우면서 지우는 것이 도움이되지만 알고리즘에 자신감이 생기면 성능의 이익에서 해당 코드를 빠르게 제거 할 수 있습니다.

쉬운 방법은 다음과 같습니다.

std::istream& data
const size_t dataSize(static_cast<size_t>(data.rdbuf()->in_avail()));
std::string content;
content.reserve( dataSize);
data.read(&content[0], dataSize);
라이센스 : CC-BY-SA ~와 함께 속성
제휴하지 않습니다 StackOverflow
scroll top