std :: istream에서 std :: string으로 직접 읽음
문제
어쨌든 임시 버퍼를 만들지 않고 알려진 바이트를 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);