2012-02-13 6 views
1

나는이 간단한 C++ 함수를 가지고있다.
문자열에서 '-'문자를 제거해야합니다.
여기에 내가 그 댓글이 명백해 생각하는 코드C++이 내 문자열을 혼합하고 있습니까?

char* FastaManager::stripAlignment(char *seq, int seqLength){ 
    char newSeq[seqLength]; 
    int j=0; 
    for (int i=0; i<seqLength; i++) { 
     if (seq[i] != '-') { 
      newSeq[j++]=seq[i]; 
     } 
    } 

    char *retSeq = (char*)malloc((--j)*sizeof(char)); 
    for (int i=0; i<j; i++) { 
     retSeq[i]=newSeq[i]; 
    } 
    retSeq[j+1]='\0'; //WTF it keeps reading from memory without this 
    return retSeq; 
} 

입니다.
나는 이유는 모르겠지만, 내가 프로그램을 실행하고 결과를 인쇄 할 때 나는 아무 잘못이 있는지 확인하기 위해 코드를 디버깅하려고하면, 나는, 그러나

'stripped_sequence''original_sequence'

뭔가를 얻을 흐름은 올바르게 진행되고 올바른 스트립 된 시퀀스를 반환합니다.

나는 여기에 두 변수의 기억을 인쇄하려고, 메모리 판독 서열에 대한

메모리 : retSeq에 대한 http://i.stack.imgur.com/UqVkX.png

메모리 : * 서열에 대한 http://i.stack.imgur.com/dHI8k.png

메모리 http://i.stack.imgur.com/o9uvI.png *의 retSeq에 대한

메모리 : http://i.stack.imgur.com/ioFsu.png

가 (때문에, 죄송합니다 스팸 필터의 링크/사진을 포함 할 수 없습니다)

이 내가 문자열 이제

for (int i=0; i<atoi(argv[2]); i++) { 
    char *seq; 
    if (usingStructure) { 
     seq = fm.generateSequenceWithStructure(structure);    
    }else{ 
     seq = fm.generateSequenceFromProfile(); 
    } 
    cout<<">Sequence "<<i+1<<": "<<seq<<endl; 
} 

에서 인쇄 사용하고 코드입니다, 나는 무슨 일이 일어나고 있는지에 대해 정말 아무 생각이 없다 에.

+4

char * 대신 std :: string을 사용할 수 있습니까? –

+0

물론 이죠.하지만 여기서 무슨 일이 일어나고 있는지 알고 싶습니다! – XelharK

+0

이것은 유효한 표준 C++가 아닙니다. 표준 C++는 가변 길이 배열을 제공하지 않습니다. – sellibitze

답변

1

이 문제는 할당 된 공간 밖에서 C 문자열의 종료 영점을 입력했기 때문에 발생합니다. 문자열 복사본 끝에 추가 문자 한 개를 할당하고 '\0'을 추가해야합니다. 또는 std::string을 사용해야합니다.

char *retSeq = (char*)malloc((j+1)*sizeof(char)); 
for (int i=0; i<j; i++) { 
    retSeq[i]=newSeq[i]; 
} 
retSeq[j]='\0'; 

it keeps reading from memory without this

으로 설계된 : C 문자열 제로 종료한다. '\0' C의 문자열 루틴에 신호를 보내 문자열의 끝 부분에 도달했음을 알립니다. C 문자열을 사용하여 작업 할 때 C++에서도 동일한 규칙이 적용됩니다.

+0

감사합니다, 당신은 내가 찾고 있던 대답을 주셨습니다! – XelharK

+0

@dasblinkenlight 예제 코드는 strncpy를 사용하여 약간 줄일 수 있습니다. –

+0

@MrLister 이것은 대부분 OP 코드입니다 (줄 10..14). 내가 한 일은 off - by - one 오류를 피하기 위해 약간 수정했다 :'-'를 제거하고, 한 곳에서'+ 1 '을 추가하고, 다른 곳에서'+ 1'을 제거했다. 나는 그것이 최적화 될 수 있다는 것을 이해하지만, 나는 가능한 한 원본에 가까이 있기를 원했다. – dasblinkenlight

2

당신이 표준 : : 문자열을 사용할 수 있다면, 간단하게이 작업을 수행 : 이것은 "erase-remove idiom"라고

std::string FastaManager::stripAlignment(const std::string& str) 
{ 
    std::string result(str); 
    result.erase(std::remove(result.begin(), result.end(), '-'), result.end()); 
    return result; 
} 

. 개인적으로

1

, 난 당신이 그렇지 않으면 정말 아주 좋은 이유가 없다면 당신은 std::string을 개시 가장 좋은 것이라고 생각 :

std::string FastaManager::stripAlignment(std::string value) 
{ 
    value.erase(std::remove(value.begin(), value.end(), value.begin(), '-'), value.end()); 
    return value; 
} 

당신이 그들이 null로 끝나는 것을 깨달을 필요가 C 문자열을 사용하고 있습니다 : C 문자열을 첫 x 째 널 문자까지 도달. 당신이 게시 한 코드로 당신은 'j'엘리먼트를 할당 할 때 범위를 벗어난 임무를 소개했고, 문자열 끝의 두 문자 인 retSeq[j + 1]에 할당합니다. 어쨌든 retSeq[j] = 0;을 의미합니다.