创建子字符串的 C 错误 - 可能是内存错误?
C bug with creating a substring - possibly a memory error?
我是 C 的新手,想知道是否可以得到一些帮助!我已经处理这个错误 15 个小时了。
所以,这个程序是一个分词器。
基本上,该程序应该接受一个字符串,或者 "token stream," 并将其分解为 "tokens." A "token" 是一个字符串,可以是单词、十六进制整数、八进制int、十进制 int、浮点 int 或符号。
我发布的代码只是出错的代码,我程序的另一部分是创建令牌的代码。
下面代码的工作原理是这样的:它需要一个 "token stream",然后从该流中找到下一个标记。完成后,它将创建 "token stream" 减去新标记的子字符串,并创建 return 作为新的 "token stream."
本质上,当字符串 "0x4356/*abdc 0777 */[]87656879jlhg kl(/j jlkh 'no thank you' /"
被传递时,程序将正确执行所有操作,但 "jlhg kl(/j jlkh 'no thank you' /"
传递时除外。一旦通过我的程序,就会创建一个 "jlhg"
令牌,但然后它会再次添加到令牌流的 end 中。因此,要分解的新令牌流变为 " kl(/j jlkh 'no thank you' / jlhg"
,其中 jlhg
被添加到末尾,之前没有。它再次做同样奇怪的事情,紧接着,但用 "kl"
代替。
它只在非常奇怪的情况下才会这样做,所以我不确定原因。我在我的程序中放置了 print 语句,一切正常进行,除了看似无处不在,程序只会在最后添加这些语句。这就是为什么我觉得它 可能 是内存问题,但我完全不知道从这里去哪里。
任何帮助将不胜感激!!!!
编辑:如果你传递字符串 "array[xyz ] += pi 3.14159e-10 A12B" 输出应该是:
字数"array"
左大括号“[
字数"xyz"
右大括号"]"
plusequals "+="
字数"pi"
浮动“3.14159e-10”
字数"A12B"
我的 TokenizerT 是这样的:
struct TokenizerT_
{
char *tokenType;
char *token;
};
typedef struct TokenizerT_ TokenizerT;
相关代码:
/*
* TKNewStream takes two TokenizerT objects.
* It will locate the index of the end of the last token,
* and create a substring with the new string to be tokenized.
* @tokenStream: old token stream
* @newToken: new token created from old token stream
*
*/
char *TKGetNextStream(char *tokenStream, char *newToken)
{
int i,
index = 0,
count = 0;
char last = newToken[strlen(newToken)-1];
for(i = 0; i < strlen(newToken); i++)
{
if(newToken[i] == last)
{
count++;
}
}
for(i = 0; i < strlen(tokenStream); i++)
{
if(tokenStream[i] == last && count == 1)
{
index = i + 1;
break;
}
else if(tokenStream[i] == last)
{
count--;
}
}
char *ret = malloc(sizeof(char)*(strlen(tokenStream) - index));
for(i = 0; i < strlen(tokenStream) - index; i++)
{
ret[i] = tokenStream[i+index];
}
return ret;
}
/*
* This is my main
*/
int main(int argc, char **argv)
{
char *string = "0x4356/*abdc 0777 */[]87656879jlhg kl(/j jlkh 'no thank you' /";
TokenizerT *newToken = malloc(sizeof(struct TokenizerT_)),
*tokenStream = malloc(sizeof(struct TokenizerT_));
tokenStream->token = string;
while(newToken != NULL)
{
newToken = TKCreate(TKGetNextToken(tokenStream));
if(newToken != NULL)
{
tokenStream->token = TKGetNextStream(tokenStream->token,
newToken->token);
printf("%s \"%s\"\n",
newToken->tokenType,
newToken->token);
}
}
TKDestroy(newToken);
return 0;
}
在 ret
中创建的字符串未正确以 null 结尾。因此,所有处理字符串的函数都将假定它继续进行,直到恰好在分配的内存之后找到下一个随机零字节。
要解决此问题,请为 ret
再分配一个 space 字节并将其设置为零,或使用 strdup()
等现有函数复制字符串:
ret = strdup(tokenStream + index);
我是 C 的新手,想知道是否可以得到一些帮助!我已经处理这个错误 15 个小时了。
所以,这个程序是一个分词器。
基本上,该程序应该接受一个字符串,或者 "token stream," 并将其分解为 "tokens." A "token" 是一个字符串,可以是单词、十六进制整数、八进制int、十进制 int、浮点 int 或符号。
我发布的代码只是出错的代码,我程序的另一部分是创建令牌的代码。
下面代码的工作原理是这样的:它需要一个 "token stream",然后从该流中找到下一个标记。完成后,它将创建 "token stream" 减去新标记的子字符串,并创建 return 作为新的 "token stream."
本质上,当字符串 "0x4356/*abdc 0777 */[]87656879jlhg kl(/j jlkh 'no thank you' /"
被传递时,程序将正确执行所有操作,但 "jlhg kl(/j jlkh 'no thank you' /"
传递时除外。一旦通过我的程序,就会创建一个 "jlhg"
令牌,但然后它会再次添加到令牌流的 end 中。因此,要分解的新令牌流变为 " kl(/j jlkh 'no thank you' / jlhg"
,其中 jlhg
被添加到末尾,之前没有。它再次做同样奇怪的事情,紧接着,但用 "kl"
代替。
它只在非常奇怪的情况下才会这样做,所以我不确定原因。我在我的程序中放置了 print 语句,一切正常进行,除了看似无处不在,程序只会在最后添加这些语句。这就是为什么我觉得它 可能 是内存问题,但我完全不知道从这里去哪里。
任何帮助将不胜感激!!!!
编辑:如果你传递字符串 "array[xyz ] += pi 3.14159e-10 A12B" 输出应该是:
字数"array"
左大括号“[
字数"xyz"
右大括号"]"
plusequals "+="
字数"pi"
浮动“3.14159e-10”
字数"A12B"
我的 TokenizerT 是这样的:
struct TokenizerT_
{
char *tokenType;
char *token;
};
typedef struct TokenizerT_ TokenizerT;
相关代码:
/*
* TKNewStream takes two TokenizerT objects.
* It will locate the index of the end of the last token,
* and create a substring with the new string to be tokenized.
* @tokenStream: old token stream
* @newToken: new token created from old token stream
*
*/
char *TKGetNextStream(char *tokenStream, char *newToken)
{
int i,
index = 0,
count = 0;
char last = newToken[strlen(newToken)-1];
for(i = 0; i < strlen(newToken); i++)
{
if(newToken[i] == last)
{
count++;
}
}
for(i = 0; i < strlen(tokenStream); i++)
{
if(tokenStream[i] == last && count == 1)
{
index = i + 1;
break;
}
else if(tokenStream[i] == last)
{
count--;
}
}
char *ret = malloc(sizeof(char)*(strlen(tokenStream) - index));
for(i = 0; i < strlen(tokenStream) - index; i++)
{
ret[i] = tokenStream[i+index];
}
return ret;
}
/*
* This is my main
*/
int main(int argc, char **argv)
{
char *string = "0x4356/*abdc 0777 */[]87656879jlhg kl(/j jlkh 'no thank you' /";
TokenizerT *newToken = malloc(sizeof(struct TokenizerT_)),
*tokenStream = malloc(sizeof(struct TokenizerT_));
tokenStream->token = string;
while(newToken != NULL)
{
newToken = TKCreate(TKGetNextToken(tokenStream));
if(newToken != NULL)
{
tokenStream->token = TKGetNextStream(tokenStream->token,
newToken->token);
printf("%s \"%s\"\n",
newToken->tokenType,
newToken->token);
}
}
TKDestroy(newToken);
return 0;
}
在 ret
中创建的字符串未正确以 null 结尾。因此,所有处理字符串的函数都将假定它继续进行,直到恰好在分配的内存之后找到下一个随机零字节。
要解决此问题,请为 ret
再分配一个 space 字节并将其设置为零,或使用 strdup()
等现有函数复制字符串:
ret = strdup(tokenStream + index);