문제

어제 약 4 시간을 코드 에서이 문제를 해결하려고 노력했습니다. 아래의 예에 대한 문제를 단순화했습니다.

아이디어는 std :: end로 끝나는 문자열에 문자열을 저장 한 다음 나중에 검색하여 원래 문자열과 비교하는 것입니다.

#include <sstream>
#include <iostream>
#include <string>

int main( int argc, char** argv )
{
    const std::string HELLO( "hello" );

    std::stringstream testStream;

    testStream << HELLO << std::ends;

    std::string hi = testStream.str();

    if( HELLO == hi )
    {
        std::cout << HELLO << "==" << hi << std::endl;
    }

    return 0;
}

아마도 추측 할 수 있듯이, 실행시 위의 코드는 아무것도 인쇄하지 않습니다.

인쇄되거나 디버거 (vs2005)에서 보았을 때 Hello and Hi는 동일하게 보이지만 .length ()는 실제로 1만큼 다릅니다. 이것이 제가 "=="연산자가 실패하게하는 것입니다.

내 질문은 이유입니다. STD :: ENDS가 왜 문자열 HI에 추가 된 보이지 않는 캐릭터인지 이해하지 못합니다. 또한이 보이지 않는 캐릭터는 부스트 트림으로 다듬어지지 않습니다. 그러나 strcmp를 사용하여 두 문자열의 .c_str ()를 비교하면 비교가 올바르게 작동합니다.

내가 STD ::를 처음 사용한 이유는 스트림 끝에 StringStream이 쓰레기 데이터를 유지하는 데 과거에 문제가 있었기 때문입니다. STD :: ENDS는 저를 위해 그것을 해결했습니다.

도움이 되었습니까?

해결책

std::ends 널 문자를 스트림에 삽입합니다. 컨텐츠를 a로 가져옵니다 std::string 그 널 문자를 유지하고 각 위치에서 해당 널 문자로 문자열을 만듭니다.

따라서 실제로 std :: 문자열에는 내장 된 널 문자가 포함될 수 있습니다. 다음 std :: 문자열 내용 ~이다 다른:

ABC
ABC\0

이진 0은 공백이 아닙니다. 그러나 인쇄 할 수 없으므로 터미널이 특별히 표시되지 않는 한 볼 수 없습니다.

사용 비교 strcmp a의 내용을 해석합니다 std::string 통과 할 때 C 문자열로 .c_str(). 말할 것입니다

흠, 첫 번째 캐릭터 \0 (널 문자 종료)입니다 알파벳, 그래서 나는 그것을 끈이다 알파벳

따라서 위의 둘 사이의 차이는 보이지 않을 것입니다. 아마도이 문제가있을 것입니다.

std::stringstream s;
s << "hello";
s.seekp(0);
s << "b";
assert(s.str() == "b"); // will fail!

StringStream이 사용하는 시퀀스는 여전히 "Hello"를 포함하는 오래된 것이기 때문에 어설 싱은 실패 할 것입니다. 당신이 한 일은 첫 번째 캐릭터를 덮어 쓰는 것입니다. 당신은 이것을하고 싶습니다 :

std::stringstream s;
s << "hello";
s.str(""); // reset the sequence
s << "b";
assert(s.str() == "b"); // will succeed!

또한이 답변을 읽으십시오. 타조 스트림 재사용 방법

다른 팁

std::ends 단순히 널 캐릭터입니다. 전통적으로 C와 C ++의 문자열은 널 (ASCII 0) 문자로 종료되지만 std::string 실제로 이것을 요구하지 않습니다. 어쨌든 당신의 코드 포인트를 통해 우리는 몇 가지 흥미로운 일이 계속되고 있습니다.

int main( int argc, char** argv )
{

문자열 문자 "hello" 전통적인 제로 종료 문자열 상수입니다. 우리는 그 전체를 std::string 안녕하세요.

    const std::string HELLO( "hello" );

    std::stringstream testStream;

우리는 이제 string 안녕하세요 (후행 0 포함)에 stream, 그 다음에 전화로 두 번째 널이 있습니다. std::ends.

    testStream << HELLO << std::ends;

우리는 우리가 넣은 물건의 사본을 추출합니다. stream (문자 문자열 "Hello", 두 개의 널 터미네이터).

    std::string hi = testStream.str();

그런 다음 두 줄을 사용하여 비교합니다 operator ==std::string 수업. 이 연산자 (아마도)는 길이를 비교합니다. string 객체 - 후행 널 캐릭터가 얼마나 많은지를 포함하여. 주목하십시오 std::string 클래스는 기본 문자 배열이 후행 Null로 끝나도록 요구하지 않습니다. 다른 방법으로 문자열에 널 문자를 포함 할 수 있도록하여 두 개의 후행 널 문자 중 첫 번째는 문자열의 일부로 처리됩니다. hi.

두 줄은 후행 널 수에서 다르기 때문에 비교가 실패합니다.

    if( HELLO == hi )
    {
        std::cout << HELLO << "==" << hi << std::endl;
    }

    return 0;
}

인쇄되거나 디버거 (vs2005)에서 보았을 때 Hello and Hi는 동일하게 보이지만 .length ()는 실제로 1만큼 다릅니다. 이것이 제가 "=="연산자가 실패하게하는 것입니다.

그 이유는 길이가 하나의 후행 널 문자로 다릅니다.

내 질문은 이유입니다. STD :: ENDS가 왜 문자열 HI에 추가 된 보이지 않는 캐릭터인지 이해하지 못합니다. 또한이 보이지 않는 캐릭터는 부스트 트림으로 다듬어지지 않습니다. 그러나 strcmp를 사용하여 두 문자열의 .c_str ()를 비교하면 비교가 올바르게 작동합니다.

strcmp 다릅니다 std::string - 문자열이 널로 끝나는 초기에 뒤로 작성되었습니다. hi 그것은 외모를 멈 춥니 다.

내가 STD ::를 처음 사용한 이유는 스트림 끝에 StringStream이 쓰레기 데이터를 유지하는 데 과거에 문제가 있었기 때문입니다. STD :: ENDS는 저를 위해 그것을 해결했습니다.

때로는 근본적인 표현을 이해하는 것이 좋습니다.

std :: end와 함께 널 숯을 추가하고 있습니다. str ()로 HI를 초기화하면 널 숯을 제거합니다. 줄은 다릅니다. strcmp는 std :: 문자열을 비교하지 않으며 char*를 비교합니다 (C 함수).

STD :: ENDS는 널 터미네이터 (char) ' 0'을 추가합니다. 널 터미네이터를 추가하기 위해 더 이상 사용되지 않은 strstream 클래스와 함께 사용합니다.

당신은 stringstream으로 그것을 필요로하지 않으며, 실제로 널 터미네이터는 "문자열을 끝내는 특수 널 터미네이터"가 아니기 때문에 stringstream에 "Stringstream은 또 다른 캐릭터 인 Zeroth 캐릭터이기 때문에 물건을 망쳐 놓습니다. StringStream 은이를 추가하면 문자 수 (귀하의 경우)가 7로 증가하고 "hello"와 비교할 수 있습니다.

현을 비교할 수있는 좋은 방법이 있다고 생각합니다. std::find 방법. C 방법을 혼합하지 마십시오 std::string ones!

라이센스 : CC-BY-SA ~와 함께 속성
제휴하지 않습니다 StackOverflow
scroll top