2016-09-01 2 views
-2

topcoder에서 발견 된 오래된 문제를 해결하려고합니다. 나는 문자열 배열에서 요소의 수를 찾으려고 노력하는 데 즉시 고생했다. 여기 내 코드는문자열 배열의 요소 계산 중 분할 오류가 발생했습니다. C++

#include <iostream> 
#include <stdio.h> 
#include <stdlib.h> 
#include <string> 

using namespace std; 

class MiniPaint { 
private: 
    size_t numLines;  

public: 
    int leastBad(string picture[], int maxStrokes) { 
     numLines = 0; 
     while (!picture[numLines].empty()) { 
      numLines++; 
     } 

     cout << numLines << '\n'; 


     return 0; 
    } 

}; 


int main() { 

    MiniPaint instance; 
    string picture[] = {"BBBBBBBBBBBBBBB", "WWWWWWWWWWWWWWW", "WWWWWWWWWWWWWWW", "WWWWWBBBBBWWWWW"}; 


    instance.leastBad(picture, 10); 
    return 0; 
} 

이 코드는 나에게 세그먼트 오류를 ​​제공합니다. 뭔가 잘못 될 것입니다, 코드는 요소의 수를 계산하는 기능에 대해 약간 과도하지만 물론 더 많은 기능을 포함하도록 클래스를 확장하려고합니다. 누군가가 여기에서 잘못되고있는 것을 설명 할 수 있다면 감사 할 것입니다! 미리 감사드립니다.

EDIT : I 어레이의 실제 요소를 표시하는, while 루프에

cout << picture[numlines] << '\n'; 

로 코드를 확장 할 때, 첫 번째 네 개의 적당한 문자열 도시하고 든 끝없이 단말기에 공간을 인쇄 . 따라서 문제는 그림에 4 개의 요소 만 있더라도

picture[4].empty() 

이 true를 반환하지 않는다는 사실에 있습니다.

+1

배열의 끝 부분을 실제로 비우기위한 'empty()'문자열이 없습니다. –

+0

그림 [4]는 배열에서 누락 된 다섯 번째 요소를 반환합니다. C/C++에서 배열 인덱스는 0부터 시작합니다. 알 수없는 메모리에 액세스하고 있으며 프로그램에서 문자열이라고 가정하고 empty() 함수를 호출합니다. 실제로는 그렇지 않을 수 있습니다. 이로 인해 세그먼트 오류가 발생합니다. –

+0

문자열 리터럴로 만든 배열에만 자동으로 종료 표시가 제공됩니다. – molbdnilo

답변

5

귀하의 while 루프 조건은 배열의 마지막 문자열이 비어 있다고 가정

int leastBad(string picture[], int maxStrokes) { 
    numLines = 0; 
    while (!picture[numLines].empty()) { 

그러나) (주에 정의 된 사용자의 입력 문자열 배열 하지입니다 종료 문자는 "" 문자열입니다.

그래서이 빈 문자열 종결 추가 할 수 있습니다 : 현대 C에서, 또한

// inside main() 

string picture[] = {..., "" /* Empty string terminator */ }; 

를 ++ 내가 배열을 컨테이너 클래스 일반적으로 대신 원시 C 스타일 배열의, std::vector<std::string>를 사용하는 것이 좋습니다 것 .

이 경우 size() 메서드를 사용하여 배열 크기 (즉, 요소 ​​수)를 얻거나 전체 배열을 반복하기위한 범위 추적 루프를 사용할 수 있습니다.

+0

감사합니다. 나는 여러분이 언급 한 컨테이너 클래스를 사용하는 것을 선호합니다. 그러나, 이것은 입력 타입이 나에게 달려 있지 않은, 해결하려고하는 topcoder 문제입니다. https://community.topcoder.com/stat?c=problem_statement&pm=1996&rd=4710 – Slugger

+0

@Slugger 문제 요구 사항은 Java 용으로 공식화되었습니다. C++로 문제를 해결하려면 그에 따라 요구 사항을 조정해야합니다. – molbdnilo

+0

아, 미안하지만 그때는 나빴어. 도움을 주셔서 감사합니다, 아직도 대답은 제가하고 싶은 일이 배열을 가리키는 것을 사용하는 것이 불가능하다는 것에 대한 더 많은 통찰력을주었습니다! – Slugger

0

배열 범위가 picture[numLines]입니다. 배열 길이를 전달하거나 그것을 계산하고 인덱스 numLines을 확인해야합니다. 코드는 다음과 같이 표시됩니다.

size_t length = sizeof(picture)/sizeof(*picture); // For VS use _countof macro 
while (numLines < length && !picture[numLines].empty()) 
{ 
    ++numLines; 
} 
+0

의견을 보내 주셔서 감사합니다. 그러나 이것은 미리 요소 수를 알고 있어야합니다. – Slugger

+0

@Slugger 중요한 것은 길이를 확인하는 것입니다. 길이를 계산할 수 있습니다. 이 질문을 확인하십시오 - [ "배열의 길이는 어떻게 찾습니까?] (http://stackoverflow.com/questions/4108313/how-do-i-find-the-length-of-an-array) – Nikita

0

범위를 벗어난 어레이에 액세스합니다.

picture[4]으로 전화를 걸면 끝내지 않은 문자열 개체에 액세스하려는 경우 empty()의 호출이 초기화되지 않은 메모리에 있습니다.

당신은 하나의 배열이 얼마나 큰 저장하고 numLines<=3 때까지 반복하는 것을 필요로하거나 벡터를 사용할 수 있습니다

std::vector<std::string> picture = ... 

for(std::string line : picture) 
{ 
    //do stuff 
} 
+0

코멘트를 위해, 그러나 이것은 미리 요소의 수를 알 필요가 있을까요? – Slugger

+0

예. 이것이 네이티브 배열의 단점입니다. 벡터는이 문제를 피하기 위해 존재합니다. 그들은 내부 배열을 가지고 있으며, 얼마나 많은 원소가 있는지를 여러분에게 알려줍니다. – Hayt

관련 문제