我正在为C ++中的家庭作业编写一个字符串标记化程序,它使用指针。但是,当我跑步&调试它,它说我的指针pStart,无效。我感觉我的问题存在于我的param'ed构造函数中,我在下面包含了构造函数和对象创建。
如果您可以告诉我为什么在调试它时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;
}
函数Next用于返回指向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 :(得分:3)
您无法在tokenizer中修改pStart
,因为C和C ++中的文字字符串不可修改,它的类型为const char *
。当你完成作业
pStart = pArray;
在你的构造函数中,pStart
现在指向一个不可修改的内存。最有可能的是你的问题。如果情况并非如此,您将需要发布更多代码。
编辑:查看编辑后,看起来您已更改代码以使用数组。非常好。我没有详细查看您的代码,但至少有一个错误:
while (pStart != NULL)
应该是:
while (pStart != NULL && *pStart)
这是因为当您点击字符串中的终止'\0'
时,您想要停止循环。
我不确定你为什么在C ++中使用C风格的字符串。这是你作业的要求吗?
答案 1 :(得分: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;
}
答案 2 :(得分:0)
将StringTokenizer类中的pStart从char *更改为const char *,并对构造函数进行相同的更改。
答案 3 :(得分: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 *,“不可能”写入它们。