(C) - 字符串数组中的第一个元素正在变成垃圾
(C) - First element in array of strings is becoming garbage
我用 C 编写了以下函数来尝试对字符串进行标记化。
该函数接收一个要标记化的字符串 (char * string),以及一串用于将标记彼此分开的定界字符 (char * delimiters)。
char ** tokenize(char * string, char * delimiters)
{
int num_of_tokens = 0;
int itr = 0;
char ** tokens = NULL;
while (string[itr] != '[=10=]')
{
if (!isDelimiter(string[itr], delimiters))
{
num_of_tokens++; /*if char is not a delimiter, we have found a new token*/
int temp_token_count = num_of_tokens - 1;
tokens = realloc(tokens, num_of_tokens);
tokens[temp_token_count] = malloc(STRING_SIZE * sizeof(char));
while(!isDelimiter(string[itr], delimiters) && string[itr] != '[=10=]')
{
appendChar(tokens[temp_token_count], string[itr]);
itr++;
}
}
itr++;
}
return tokens;
}
在 main 函数中,对 tokenize 函数的调用如下所示:
int main()
{
char * string = "This would,,,,be";
char * delim = ",.:;*& ";
char ** tokens = tokenize(string, delim);
int x = 0;
while(x<3)
{
printf("%s\n", tokens[x]);
x++;
}
return 0;
}
我希望此调用的输出产生:
This
would
be
然而,这是正在输出的内容:
L@?
would
be
考虑到如果我使用 "This," 作为输入字符串调用 tokenize 函数,我收到的结果也正是我所期望的:
This
我不知道发生了什么事,非常感谢您的帮助,感谢您的宝贵时间!!
编辑:这是 isDelimiter 函数
int isDelimiter(char test_char, char * delimiters)
{
int itr = 0;
while (delimiters[itr] != '[=15=]')
{
if (test_char == delimiters[itr]) return 1;
itr++;
}
return 0;
}
这是不正确的:
tokens = realloc(tokens, num_of_tokens);
由于tokens
被用作指针数组,您需要为num_of_tokens
个指针分配space:
tokens = realloc(tokens, num_of_tokens * sizeof(char *));
此外,当您找到一个标记时,您将在另一个 while
循环中遍历该字符串,直到找到一个分隔符或 NULL。这很好,但是您随后会在外部 while
循环的底部再次递增 itr
。如果您在内部循环的末尾发现 NULL,此增量会将索引移到字符串范围之外,从而导致未指定的行为。
如果找不到定界符,您应该只在外循环中递增:
while (string[itr] != '[=12=]')
{
if (!isDelimiter(string[itr], delimiters))
{
...
}
else
{
itr++
}
}
我用 C 编写了以下函数来尝试对字符串进行标记化。 该函数接收一个要标记化的字符串 (char * string),以及一串用于将标记彼此分开的定界字符 (char * delimiters)。
char ** tokenize(char * string, char * delimiters)
{
int num_of_tokens = 0;
int itr = 0;
char ** tokens = NULL;
while (string[itr] != '[=10=]')
{
if (!isDelimiter(string[itr], delimiters))
{
num_of_tokens++; /*if char is not a delimiter, we have found a new token*/
int temp_token_count = num_of_tokens - 1;
tokens = realloc(tokens, num_of_tokens);
tokens[temp_token_count] = malloc(STRING_SIZE * sizeof(char));
while(!isDelimiter(string[itr], delimiters) && string[itr] != '[=10=]')
{
appendChar(tokens[temp_token_count], string[itr]);
itr++;
}
}
itr++;
}
return tokens;
}
在 main 函数中,对 tokenize 函数的调用如下所示:
int main()
{
char * string = "This would,,,,be";
char * delim = ",.:;*& ";
char ** tokens = tokenize(string, delim);
int x = 0;
while(x<3)
{
printf("%s\n", tokens[x]);
x++;
}
return 0;
}
我希望此调用的输出产生:
This
would
be
然而,这是正在输出的内容:
L@?
would
be
考虑到如果我使用 "This," 作为输入字符串调用 tokenize 函数,我收到的结果也正是我所期望的:
This
我不知道发生了什么事,非常感谢您的帮助,感谢您的宝贵时间!!
编辑:这是 isDelimiter 函数
int isDelimiter(char test_char, char * delimiters)
{
int itr = 0;
while (delimiters[itr] != '[=15=]')
{
if (test_char == delimiters[itr]) return 1;
itr++;
}
return 0;
}
这是不正确的:
tokens = realloc(tokens, num_of_tokens);
由于tokens
被用作指针数组,您需要为num_of_tokens
个指针分配space:
tokens = realloc(tokens, num_of_tokens * sizeof(char *));
此外,当您找到一个标记时,您将在另一个 while
循环中遍历该字符串,直到找到一个分隔符或 NULL。这很好,但是您随后会在外部 while
循环的底部再次递增 itr
。如果您在内部循环的末尾发现 NULL,此增量会将索引移到字符串范围之外,从而导致未指定的行为。
如果找不到定界符,您应该只在外循环中递增:
while (string[itr] != '[=12=]')
{
if (!isDelimiter(string[itr], delimiters))
{
...
}
else
{
itr++
}
}