2012-03-02 2 views
0

중간에 null 문자를 포함 할 수있는 문자열을 char 배열로 복사하려고합니다. 다음 함수를 생성했습니다.문자열을 char 배열로 복사

void SaveStringToChar(string &mystring,const char * &ArrChar) 
{//begin function 

    std::string str; 
    char * writable = new char[str.size() + 1]; 
    std::copy(str.begin(), str.end(), writable); 
    writable[str.size()] = '\0'; 
    ArrChar = writable; 

}//end function 

내 질문에이 메서드는 null 요소 뒤에 문자를 잃지 않을 것을 보장합니다. 그리고 내 다른 질문은 내가 무슨 뜻인지 모르겠다는이 링커 오류가 있습니다.

/tmp/ccUpCRaz.o : 함수에서 :: RuleParser`파서 (숯 CONST *) '. Parser.cpp :(텍스트 0x3f6 +) : 파서 ​​:: SaveStringToChar (STD에 정의되지 않은 참조 : basic_string, 표준 : : 할당> &, 숯불 CONST * &) ' collect2 : 신분증 1 개 종료 상태를 반환

anyhint하시기 바랍니다.

이것은 비교할 물건을 전달하는 기능입니다.

void Search(size_t TextLength, const char *Text, const vector<const char *> &patterns); 
+0

로 변경, 당신은 왜 ['표준 : : 문자열 :: c_str()'(http://www.cplusplus.com/reference/string/string/c_str를 사용하지 않는 /)? – ereOn

+0

나는 그것들을 사용했으나 내 문자열에 중간에 null이 들어있을 수있다. 나는 그 문자열이 벡터의 데이터를 다시 검사하고 잃어버린 것을 발견했기 때문에 const char * 형식의 벡터에 푸시하여 잃어 버렸다고 생각했다. – user1231229

+0

c_str() 함수의 결과가 첫 번째'\ 0'을 지나서 모든 문자를 포함하는 것이 확실하다면 확실하지 않습니다. 하나의 컴파일러로 테스트하더라도 동일한 방식으로 다른 컴파일러에서 작동하지 않을 수 있습니다. –

답변

2

이 기능을 Parser::의 구성원으로 정의해야합니다.

void Parser::SaveStringToChar(string &mystring,const char * &ArrChar) 

std::copy() 모든 문자를 복사합니다 :

void SaveStringToChar(string &mystring,const char * &ArrChar) 

변경에 : 현재로 정의한다. 그러나 호출자는 이 실제로 얼마나 많은 문자 (예 : strlen())를 가리키는 지 알 수 없으므로 첫 번째 null 문자에서 계산이 중지됩니다. SaveStringToChar()의 서명을 의 문자 수로 채워지는 또 다른 인수 size_t& ArrCharLen을 허용하도록 변경할 수 있습니다. 물론 mystring의 길이는 ArrChar이므로 SaveStringToChar()으로 전화하기 전에 이미 저장하고 있습니다.

EDIT (vector<const char*> 코멘트 후) 다음 const char*vector에 추가되면

바이트의 진정한 수는 손실됩니다. vector<std::string>을 사용하지 않고 실제로 std::string에 몇 개의 문자가 저장되어 있는지 알고 싶다면 std::string::length()을 사용해야합니다.

EDIT2은 (text.length와 비교 함수 .c_str() 후 :

대신 vector<const char*> 요소와 비교할 .c_str().length()를 전달

단지 비교 기능 요소에 대해 비교할 std::string 합격 vector<std::string> : 제대로 문자열을 비교합니다 std::string::operator==()는 null 문자를 포함합니다 그런 다음 파일에서 읽은 std::stringvector<std::string>를 검색 할 std::find()를 사용할 수 있습니다 당신이를 통과하는 그 일을하는 경우

+0

당신은 요점을 가지겠습니까?하지만 이것은 단순한 비교가 아닙니다. 검색 기능은 실제로 이러한 매개 변수를 기반으로하는 알고리즘이므로, 내 매개 변수를 변경할 수는 없습니다. 진실 나는 그것을 문자열로 바꿔 보려고했지만, 내가 해결할 수없는 오류가 쌓였다.) – user1231229

+0

'Text'와'TextLength'를'vector'의 엔트리와 비교하는 데 당신은 무엇을 사용합니까? 'vector '으로 변경하는 것이 가장 간단한 방법 인 것 같습니다. – hmjd

+0

필요한 경우'std :: string []'을 사용하여 각 개별 문자에 계속 액세스 할 수 있습니다. – hmjd

1

귀하의 문자열을 복사 잘 보이지만,.. 숯불 * 더 나은 방법이 있습니다 :

std::string str; 
//... 
my_func(str.c_str()); 

hmjd에 링크 오류가 있습니다.

0

링크 오류에 대한 hmjd의 대답을 참조하십시오.

복사 된 문자에 대해서는 은 모두 출력 버퍼에 안전하게 복사되기 때문에 문자를 잃지 않습니다. 그러나 문자열 중간에 실제로 \0 문자가있는 경우 C 스타일 문자열 함수 (예 : printf)가 올바르게 작동하지 않습니다.
또한 호출 루틴은 문자열의 길이가 무엇인지 알 수 없으므로 새로 할당 된 버퍼 크기를 알 수 없습니다. 반환 값이나 다른 참조 인수로 문자열 길이를 반환해야합니다.

+0

괜찮 았어. 배열처럼 그들은 내가 A와 같이 통과 할 때 거기에있을 것이다. A null B C null null – user1231229

+0

나는 그것을 인쇄용으로 사용하지 않기 때문에 나는 그것을 비교 목적으로 사용하고있다. – user1231229

+0

정확한 길이가 무엇인지 알면 OK. 그렇지 않으면 C 스타일 비교 함수가 제대로 작동하지 않습니다. 그건 그렇고,'std :: string's와 비교하는 것이 가능합니다. 문자 배열로 먼저 복사 할 필요가 없습니다. –

0

내 질문이 방법은 널 (null) 문자가 포함 된 경우에도 나는 늘, 전체 문자열을 버퍼에 복사됩니다 널 요소

후 문자를 잃을 것을 보장합니다. std::copy은 어떤 식 으로든 복사하는 데이터를 해석하지 않으며, 사용자가 지정한 요소의 수만 복사합니다. 문자열이 널 (null) 문자를 포함 않을 경우

그러나, 당신은 (예 : <cstring>에있는 것과 같은) 널 (null)로 종료되는 문자열과 함께 작동 어떤 기능을 사용하지 수 그들은 첫 번째 널 문자를 문자열의 끝으로 해석합니다.

또한 게시 한 코드에서 적어도 포인터를 const char *으로 돌려 놓으므로 사본을 수정하지 않을 것임을 의미합니다. 이 경우 실제로 문자열 데이터의 복사본이 필요하거나 대신 str.c_str()을 반환 할만큼 충분합니까?

내 다른 질문은 당신이 Parser::SaveStringToChar의 정의를 놓치고처럼 보이는이 링커 오류

를 얻을 수있다. 내가 게시 한 코드가 소스 파일에서 왔으며 Parser 클래스 내부에서 정의 된 함수가 아니라고 추측합니다. 그렇다면 멤버 함수라는 것을 잊어 버리고 멤버가 아닌 멤버를 대신 정의해야합니다. 호기심

void Parser::SaveStringToChar(string &mystring,const char * &ArrChar) 
    ^^^^^^^^ 
관련 문제