2010-02-06 54 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的指針的char數組中返回到下一個字。目前尚未完成。 :)

完全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 2010-02-06 03:21:49

+0

'CXX0030:錯誤:表達式無法評估'謝謝! – Alex 2010-02-06 03:23:23

+0

CXX003是一個C/C++運行時/編譯時錯誤,但在調試器中出現錯誤,說錯誤地使用了值評估器 - http://msdn.microsoft.com/en-us/library/ 360csw6a(VS.71).aspx 如果你能發送更完整的代碼會更好。你粘貼的位在這種形式中是不完整和不正確的,即pStart是什麼? – mloskot 2010-02-06 03:26:48

回答

0

將StringTokenizer類中的pStart從char *更改爲const char *,並對構造函數進行相同的更改。

+0

謝謝!項目的主要幫助! – Alex 2010-02-06 03:49:00

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 2010-02-06 03:25:33

+0

我正在讀取char數組中的方式 – Alex 2010-02-06 03:26:17

+0

請添加更多信息。你看,字符串文字是CONSTANT,你不能以任何方式改變它。我認爲你實際上將它分配給另一個char *,你不能,你必須將它分配給另一個const char *。 我將編輯答案,讓我看到一些實際的代碼,正如我想的那樣。 – Spidey 2010-02-06 03:28:39

3

您不能修改pStart在你的標記生成器,因爲在C和C++一個字符串是不可修改的,它有一個類型const char *。當您在構造函數中做作業

pStart = pArray; 

pStart現在指向一個不可修改的內存。最有可能的是你的問題。如果情況並非如此,您將需要發佈更多代碼。

編輯:看完您的編輯之後,看起來您已將您的代碼更改爲使用數組。那很好。我沒有太多的細節看你的代碼,但至少有一個錯誤:

while (pStart != NULL) 

應該是:

while (pStart != NULL && *pStart) 

這是因爲要停止你的循環,當你打在您的字符串中終止'\0'

我不確定你爲什麼在C++中使用C風格的字符串。這是你家庭作業的要求嗎?

+0

如果我使用char數組,它會改變什麼嗎? – Alex 2010-02-06 03:27:31

+0

char數組在哪裏?如果'pStart'是一個char數組,那麼這個賦值甚至不會編譯:你不能在C++中賦值給數組。請發佈最少的完整代碼。 – 2010-02-06 03:29:02

0

在我看來,你應該改變的StringTokenizer的構造函數和析構函數:

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

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

現在你可以使用PSTART在你的方式使用它:修改字符串,把零,以紀念的話,等等。你只需要爲StringTokenizer添加一個「char * str」私有屬性。

這裏的訣竅是您正在創建自己的字符串副本,因此您可以隨意操縱,只要您將其釋放到析構函數中即可。唯一的缺點是你需要內存來存儲副本(所以你需要兩次內存的每個字符串)。

您的解決方案無法正常工作的原因是文字是或可以存儲在只讀存儲器中,因此它們被正確標記爲const char *,寫入它們是「不可能的」。