2010-02-06 1 views
3

포인터를 사용하는 C++의 숙제를위한 문자열 토큰 화 프로그램을 작성하고 있습니다. 그러나 & 디버그를 실행하면 포인터 pStart가 유효하지 않다고 표시됩니다. 내 문제가 내 param'ed 생성자에 있다는 느낌이 들었습니다. 아래에서 생성자와 객체 생성을 모두 포함했습니다.불량 포인터? - C++

디버깅 할 때 pStart가 나쁜 포인터라는 이유를 설명해 주시면 감사하겠습니다.

감사합니다.

StringTokenizer::StringTokenizer(char* pArray, char d) 
{ 
pStart = pArray; 
delim = d; 
} 

// create a tokenizer object, pass in the char array 
// and a space character for the delimiter 
StringTokenizer tk("A test char array", ' '); 

전체 stringtokenizer.cpp :

#include "stringtokenizer.h" 
#include <iostream> 
using namespace std; 

StringTokenizer::StringTokenizer(void) 
{ 
pStart = NULL; 
delim = 'n'; 
} 

StringTokenizer::StringTokenizer(const char* pArray, char d) 
{ 
pStart = pArray; 
delim = d; 
} 

char* StringTokenizer::Next(void) 
{ 
char* pNextWord = NULL; 

while (pStart != NULL) 
{ 
    if (*pStart == delim) 
    { 
     *pStart = '\0'; 
     pStart++; 
     pNextWord = pStart; 

     return pNextWord; 
    } 
    else 
    { 
     pStart++; 
    } 
} 
    return pNextWord; 
} 

다음 문자 배열은 다음 단어에 대한 포인터를 리턴하는 함수 supossed된다. 현재 완료되지 않았습니다. :)

전체 stringtokenizer.h :

#pragma once 

class StringTokenizer 
{ 
public: 
StringTokenizer(void); 
StringTokenizer(const char*, char); 
char* Next(void); 
~StringTokenizer(void); 
private: 
char* pStart; 
char delim; 
}; 

전체 MAIN.CPP :

const int CHAR_ARRAY_CAPACITY = 128; 
const int CHAR_ARRAY_CAPCITY_MINUS_ONE = 127; 

// create a place to hold the user's input 
// and a char pointer to use with the next() function 
char words[CHAR_ARRAY_CAPACITY]; 
char* nextWord; 

cout << "\nString Tokenizer Project"; 
cout << "\nyour name\n\n"; 
cout << "Enter in a short string of words:"; 
cin.getline (words, CHAR_ARRAY_CAPCITY_MINUS_ONE); 

// create a tokenizer object, pass in the char array 
// and a space character for the delimiter 
StringTokenizer tk(words, ' '); 

// this loop will display the tokens 
while ((nextWord = tk.Next ()) != NULL) 
{ 
    cout << nextWord << endl; 
} 


system("PAUSE"); 
return 0; 
+0

받고있는 오류 메시지는 무엇입니까? – ihtkwot

+0

'CXX0030 : 오류 : 표현식을 평가할 수 없습니다. '감사! – Alex

+0

CXX003은 C/C++ 런타임/컴파일 타임 오류가 아니라 디버거에서 오류가 발생하여 값 평가자를 잘못 사용한다고 오류가 발생했습니다 - http://msdn.microsoft.com/en-us/library/ 360csw6a (VS.71) .aspx 더 완벽한 코드를 보낼 수 있다면 더 좋을 것입니다. 붙여 넣은 비트가이 형식에서 불완전하고 잘못되었습니다. 즉, pStart는 무엇입니까? – mloskot

답변

0

StringTokenizer 클래스의 pStart를 char *에서 const char *로 변경하고 동일한 변경을 생성자에 적용합니다. 단어를 표시하기 위해 문자열을 수정, 제로 퍼팅 :

StringTokenizer::StringTokenizer(char* pArray, char d) 
{ 
    pStart = str = strdup(pArray); 
    delim = d; 
} 

StringTokenizer::~StringTokenizer(char* pArray, char d) 
{ 
    free(str); 
} 

지금 당신은 당신이 그것을 사용하는 방법으로 pStart를 사용할 수 있습니다 제 생각에는

+0

감사합니다! 프로젝트에 대한 주요 도움! – Alex

1

변경

StringTokenizer::StringTokenizer(char* pArray, char d) 

StringTokenizer::StringTokenizer(const char * pArray, char d) 
,

문자열 리터럴은 항상 const char * const 변수이며 C++은 const가 아닌 const를 자동으로 캐스팅하므로 const가 아닌 const로 캐스팅 할 수 없습니다.

다른 생성자를 만들 수도 있지만 pArray 문자열을 읽는 한 필요하지는 않습니다.

이 같은 것을 사용할 수 있습니다

TokenList& StringTokenizer::StringTokenizer(const char* pArray, char d){ 
    TokenList lst(); 
    size_t i=0; 
    char buffer[100]; //hardcoded limit, just an example, you should make it grow dinamically, or just use a std::string 
    while((*pArray)){ 
    if(*pArray == d){ 
     buffer[i] = 0; //string ending character, 0 = '\0'; 
     lst.add(buffer); 
     i=0; 
    } 
    pArray++; 
    } 
    //Last token in the input string won't be ended by the separator, but with a '\0'. 
    buffer[i] = 0; 
    lst.add(buffer); 

    return lst; 
} 
+0

이제 오류 메시지가 나타납니다. '오류 C2440 :'= ':'const char * '에서'char * '로 변환 할 수 없습니다. – Alex

+0

방법으로 문자 배열을 읽는 중입니다. – Alex

+0

자세한 정보를 추가하십시오. 문자열 리터럴은 상수입니다. 어떤 식 으로든 변경할 수는 없습니다. 나는 당신이 실제로 그것을 다른 char *에 할당한다고 생각합니다. 당신은 그것을 다른 const char *에 할당해야합니다. 나는 생각하고있는 것처럼 실제 코드를 약간 보여주기 위해 답을 편집 할 것이다. – Spidey

3

당신은 C와 C++에서 리터럴 문자열을 수정할 수 없습니다 때문 유형 const char *을 가지고, 당신의 토크 나이에 pStart을 수정할 수 없습니다. 당신이 당신의 생성자에서 할당을

pStart = pArray; 

을 수행 할 때 pStart 이제 수정 불가능한 메모리를 가리키고 있습니다. 가장 가능성있는 것은 문제입니다. 그렇지 않은 경우 더 많은 코드를 게시해야합니다.

편집 : 편집을보고 나면 배열을 사용하도록 코드를 변경 한 것처럼 보입니다. 좋습니다. 내가 너무 많은 세부 사항에 코드를보고하지 않은,하지만 적어도 하나의 오류가 :

while (pStart != NULL) 

가 있어야한다 : 당신은 당신이 명중 할 때 루프를 중지하려면 때문에

while (pStart != NULL && *pStart) 

이것은이 문자열에서 '\0'을 종료하십시오.

C++에서 C 스타일 문자열을 사용하는 이유가 확실하지 않습니다. 숙제에서 이것이 요구 사항입니까?

+0

문자 배열을 사용하는 경우 아무 것도 변경되지 않습니까? – Alex

+0

char 배열 어디? 'pStart'가 문자 배열이면, 할당은 컴파일되지도 않을 것입니다 : C++에서 배열에 할당 할 수 없습니다. 최소한의 완전한 코드를 기재하십시오. –

0

, 당신은 있고 StringTokenizer의 생성자와 소멸자를 변경해야 StringTokenizer에 "char * str"전용 속성을 추가하기 만하면됩니다.

여기에있는 속임수는 문자열의 복사본을 직접 생성하므로 소멸자에서 해제하면 원하는대로 어쨌든 조작 할 수 있습니다. 유일한 단점은 복사본을 저장하기 위해 메모리가 필요하다는 것입니다 (따라서 각 문자열에 대해 두 번 메모리가 필요합니다).

솔루션이 작동하지 않는 이유는 리터럴이 읽기 전용 메모리에 저장되거나 저장 될 수 있기 때문에 const char *로 올바르게 표시되기 때문에 쓰기가 불가능하다는 것입니다.