2010-01-13 4 views
7

TCHAR[256]과 같이 버퍼의 주소를 사용하는 Win32 함수가 많이 있으며 그 버퍼에 일부 데이터를 씁니다. 버퍼의 크기보다 작거나 전체 버퍼 일 수 있습니다.char [] 버퍼를 사용하는 Win32 함수로 std :: string을 혼합하는 방법은 무엇입니까?

종종 스트림이나 파이프에서 데이터를 읽는 것과 같이 루프로 호출합니다. 결국이 데이터를 검색하기 위해 모든 반복 호출에서 전체 데이터가있는 문자열을 효율적으로 반환하고 싶습니다. 나는 + =가 Java와 비슷한 방법으로 최적화되었거나 C#의 StringBuffer.append()/StringBuilder.Append() 메쏘드로 메모리 대신에 속도를 선호하기 때문에 std::string을 사용하려고 생각했다.

그러나 std::string과 Win32 함수를 공동으로 사용하는 것이 가장 좋은 방법인지는 모르겠지만이 함수는 char[]부터 시작합니다. 어떤 제안?

답변

6

std::string는 이에 상응하는 C 스타일의 문자열을 반환하는 함수 c_str() 있습니다. (const char *)

std::string에는 C 스타일 문자열을 입력으로 사용하는 오버로드 된 할당 연산자가 있습니다.

ssstd::string 예를하자 다음 상호과 같이 수행 할 수있는 C 스타일의 문자열이 될 sc :

ss = sc; // from C-style string to std::string 
sc = ss.c_str(); // from std::string to C-style string 

UPDATE : 마이크 웰러는 지적

, UNICODE 매크로가 정의 된 경우, 문자열은 wchar_t*이 될 것이므로 std::wstring을 대신 사용해야합니다.

+1

TCHAR은 UNICODE 매크로의 값에 따라 변경됩니다. UNICODE가 정의되면 문자열은 wchar_t *가되고 대신 std :: wstring을 사용해야합니다. –

+1

문자열을'std :: string' 내부 버퍼에 직접 쓰는 것은 위험 할 수 있습니다. 왜냐하면 문자열은 길이를 바꿀 수있는 길이를 저장하기 때문에 위험 할 수 있습니다. –

+0

Idan이 정확합니다. 문자열 버퍼에 쓸 함수에 std :: string을 사용하지 마십시오. – jmucchiello

6

std :: string 대신 std::vector을 사용하고 v.size()을 사용하는 동안 &v.front()을 사용하는 것이 좋습니다. 이미 할당 된 공간이 있는지 확인하십시오!

std::string 및 이진 데이터에주의해야합니다.

s += buf;//will treat buf as a null terminated string 
s += std::string(buf, size);//would work 
+1

벡터의 초기 크기를 ctor로 설정하거나 'resize()'를 호출하는 것이 좋습니다. 그 다음 버퍼의 길이로'size()'를 전달하십시오. –

+0

@Mike Weller : 아래 표를 가져 주셔서 감사합니다 ... 귀하의 요점이 무엇인지 보지 못했습니다 .data()는 어때요? 물론 .c_str()은 무엇을하는지 알지만, OP는 함수가 버퍼를 사용한다고 말했고 임의의 바이너리 데이터의 경우 std :: string 대신 std :: vector를 사용하는 것이 더 좋습니다. –

+0

크기 설정 생성자를 사용하여 벡터를 만들거나 resize()를 호출해야합니다. –

11

인수 대신 이런 입력/출력 사용 std::vector<char> 경우 인수이

std::string text("Hello"); 
w32function(text.c_str()); 

입력 전용 사용 std::string 인 경우 :

std::string input("input"); 
std::vector<char> input_vec(input.begin(), input.end()); 
input_vec.push_back('\0'); 
w32function(&input_vec[0], input_vec.size()); 
// Now, if you want std::string again, just make one from that vector: 
std::string output(&input_vec[0]); 

인수이면 출력 전용도 다음과 같이 std::vector<Type>을 사용하십시오.

// allocates _at least_ 1k and sets those to 0 
std::vector<unsigned char> buffer(1024, 0); 
w32function(&buffer[0], buffer.size()); 
// use 'buffer' vector now as you see fit 

std::basic_string<TCHAR>std::vector<TCHAR>을 사용할 수도 있습니다.

자세한 내용은 Effective STL Scott Meyers 저널을 참조하십시오.

2
  • 호환되는 문자열 유형이 필요합니다. typedef std::basic_string<TCHAR> tstring;은 좋은 선택입니다.

  • 입력 전용 인수의 경우 .c_str() 메소드를 사용할 수 있습니다.

    버퍼를 들어
  • , 선택은 약간 덜 분명하다

표준 : : basic_string가 표준처럼 연속 스토리지를 사용하도록 보장 할 수 없습니다 : 벡터이다. 그러나 내가 본 모든 std :: basic_string 구현은 연속 된 저장소를 사용하며 C++ 표준위원회는 누락 된 보증을 표준의 결함으로 간주합니다. 결함은 C++ 0x 초안에서 수정되었습니다.

부정적인 결과가없는 규칙을 약간만 구부릴 수 있다면 & (* aString.begin())을 길이가 aString.size() 인 TCHAR 버퍼에 대한 포인터로 사용할 수 있습니다. 그렇지 않으면, 당신은 std :: vector로 지금 당장 붙어 있습니다.

가 구현을 더 많은 자유를 제공하지 않습니다이 기존 연습을 표준화하지 :

다음은 C++ 표준위원회는 연속 된 문자열 저장에 대해 무슨 말을했는지입니다. 우리는 십 년 전에 일 수도 있다고 생각했습니다. 그러나 공급 업체는 구현과 함께 음성을 사용하고 LWG 회의에서는 음성을 과 함께 사용합니다. 표준 에 관계없이 구현은 연속 될 것입니다. 그래서 표준은 문자열 클라이언트에게 더 많은 디자인을 줄 수도 있습니다. 선택.

관련 문제