2012-04-11 2 views
4

read()에 std :: string을 사용할 수 있습니까?read()에 std :: string을 사용할 수 있습니까?

예 :

std::string data; 

read(fd, data, 42); 

이 Normaly, 우리가 숯불 *를 사용해야하지만, 직접 표준 : : 문자열을 사용할 수 있습니까? 읽기 기능은 더 후, 숯불 *이 필요한 경우

감사의

+0

zero-copy가 목표라면, "read"를 "mmap"으로 바꾸고 고정 할당 된 std :: string을 감싸는 데 도움이 될까요? – user1202136

+0

읽고있는 문자열에 공백이 있습니까? –

답변

7

글쎄, 기능에 필요한 것이므로 어떻게 든 char*을 만들어야합니다. (BTW : 당신은 POSIX의 기능 read에 대해하지 않는 이야기, 그리고 std::istream::read입니까?) 문제는 char*, 그것은에 char* 포인트 (I 용의자 당신이 실제로 무엇을 의미하는지 입니다) 무엇 없습니다.

간단하고 일반적인 해결책은 여기에 로컬 배열을 사용하는 것입니다 : 당신이 std::string에 직접 캡처 할 경우

char buffer[43]; 
int len = read(fd, buffer, 42); 
if (len < 0) { 
    // read error... 
} else if (len == 0) { 
    // eof... 
} else { 
    std::string data(buffer, len); 
} 

을하지만,이 가능 (비록 반드시 좋은 생각)입니다 :

std::string data; 
data.resize(42); 
int len = read(fd, &data[0], data.size()); 
// error handling as above... 
data.resize(len); // If no error... 

이 사본을 피할 수 있지만, 솔직히 ... 복사 시간에 비해 실제 읽기에 필요한 미미하고 할당 O를위한 f 문자열에있는 메모리. 이것은 실제로 읽은 문자에 대해 최소값 인 이 아니라 4235 바이트의 실제 버퍼 (결과가 반올림 됨)을 갖는 결과 문자열의 (아마도 무시할 수있는) 단점을 가지고 있습니다.

(그리고 사람들이 때때로 std:;string에서 메모리의 연속성 관련하여 문제를 제기 이후 :이 10 개 이상의 년 전 문제였다 std::string의 원래 사양은 expressedly 비 연속 수 있도록 을 설계되었습니다. 구현에서, 클래스의 인기있는 rope 클래스를 따르고 있습니다. 실제로 구현 자는이 이 유용하다는 것을 발견하지 못했고 사람들은 연속성을 가정하기 시작했습니다.어떤 시점에서 표준위원회는 기존의 연습과 표준을 맞추기로 결정 했으므로 인접성이 필요합니다. 따라서 ... 이 연속적으로 실행되지 않았으며 향후 구현으로 인해 연속성이 보장되지 않습니다.

+0

"이것은 사본을 피할 수 있지만 솔직히 ... 사본은 실제 읽기와 배정에 필요한 시간에 비해 중요하지 않습니다. 문자열의 메모리. " 읽을 데이터의 크기에 따라 다릅니다. 사람들은 여러 데이터 전송 경로에서 Linux 커널을 제로 카피로 만드는 데 많은 노력을 기울였습니다. – user1202136

+0

@ user1202136이 경우 복사본의 크기는 42 바이트입니다. 동적 할당과 시스템에서 바이트 전송이 있습니다. 상황은 버퍼와 같은 것을 처리 할 때 적어도 커널에서 다르다. (4KB 이상의 순서 일 가능성이 있고 풀에서 할당된다.) –

0

(I 점포 결과에 대한 숯불 *을 생성하지 않는 선호). char의 std :: vector의 첫 번째 요소의 주소를 사용할 수 있습니다. 먼저 크기를 조정해야합니다. 나는 old (pre C++ 11) 문자열이 인접한 메모리를 가지기를 바란다고 생각하지 않는다. 그렇지 않으면 문자열과 비슷한 것을 할 수있다.

0

아니요, 할 수 없으며 그렇게해서는 안됩니다. 일반적으로 std :: string 구현체는 내부적으로 할당 된 메모리의 크기와 실제 문자열의 길이와 같은 다른 정보를 저장합니다. C++ 설명서는 c_str() 또는 data()에 의해 반환 된 값을 수정하면 정의되지 않은 동작이 발생 함을 명시 적으로 설명합니다.

0

아니,

std::string data; 
cin >> data; 

작품 잘. read(2)의 동작을 실제로 원한다면 문자의 자체 버퍼를 할당하고 관리해야합니다.

+0

공백이 깨집니다. –

+2

우리가 질문에서 알 수있는 모든 것이 바람직 할 수도 있습니다 ... – DRVic

0

read()는 원시 데이터 입력을위한 것이기 때문에 std :: std :: string은 텍스트를 처리하기 때문에 string은 실제로 나쁜 선택입니다. std :: vector는 원시 데이터를 처리하는 올바른 선택처럼 보입니다.

-1

문자열 라이브러리에서 std :: getline 사용 - cplusplus.com 참조 - 스트림에서 읽고 문자열 개체에 직접 쓸 수 있습니다. 예를 (다시 cplusplus.com에서 리핑 - 1 일의 getline을 위해 구글에 명중) : 표준 입력 (CIN) 및 파일 (ifstream)에서에서 읽을 때

int main() { 
    string str; 
    cout << "Please enter full name: "; 
    getline (cin,str); 
    cout << "Thank you, " << str << ".\n"; 
} 

그래서 작동합니다.

+0

왜 관련이 있습니까? read는 posix의 시스템 호출이며 콘솔 인과 관련이 없습니다. –

관련 문제