免责声明:这是家庭作业的一部分,但不是整个作业。
我的任务是创建一个“tokenizer”对象,通过每次调用TKGetNextToken返回一次,检索由空格分隔的标记,并对返回的标记执行一系列操作。
但TKGetNextToken函数的行为并不应该如此。应该发生的是:
但是,该函数不会在字符串的末尾停止,而是直接吹过它并打印出内存中的所有内容,直到程序崩溃。我无法弄清楚为什么会这样。
这是代码
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <ctype.h>
struct TokenizerT_ {
char *currentToken;
};
typedef struct TokenizerT_ TokenizerT;
char *TKGetNextToken(TokenizerT *tk) {
char *cp = tk->currentToken;
while (cp != NULL && isspace(*cp)) {
cp++;
}
if (cp == NULL) {
tk->currentToken = NULL;
return NULL;
}
int size = 0;
char *token = malloc(sizeof(char));
while (cp != NULL && !isspace(*cp)) {
size++;
token = realloc(token, size * sizeof(char));
token[size - 1] = *cp;
cp++;
}
token = realloc(token, (size + 1) * sizeof(char));
token[size] = NULL;
tk->currentToken = cp;
return token;
}
TokenizerT *TKCreate(char *ts) {
TokenizerT *tokenizer = malloc(sizeof(TokenizerT));
tokenizer->currentToken = ts;
return tokenizer;
}
void TKDestroy(TokenizerT *tk) {
free(tk);
}
int main(int argc, char **argv) {
TokenizerT *tok = TKCreate(argv[1]);
char *token = TKGetNextToken(tok);
while (token) {
printf("\'%s\'\n", token);
token = TKGetNextToken(tok);
}
TKDestroy(tok);
return 0;
}
以下是命令行参数“100 200 300 400”的示例输出。它显然是从输入字符串之外的内存中打印出来的。
'100'
'200'
'300'
'400'
''
'╘jÉ'
'╘hÉ'
''
''
''
''
''
从gdb输出
Program received signal SIGSEGV, Segmentation fault.
0x00401476 in TKGetNextToken (tk=0x701720) at test.c:28
28 while (cp != NULL && !isspace(*cp)) {
(gdb) backtrace
#0 0x00401476 in TKGetNextToken (tk=0x701720) at test.c:28
#1 0x0040151e in main (argc=2, argv=0x700cf0) at test.c:60
答案 0 :(得分:2)
在你的两个while
循环中,条件应该包括对空字符的测试。 “没有遇到字符串末尾的空字符”的相应测试是*cp
,因此使用:
while ( cp != NULL && *cp && !isspace( *cp ) )
我感觉cp != NULL
测试是一个没有更多令牌的测试,在这种情况下,它们可能应该被排除在while
循环之外。如果这是错误的并且它们是字符串结尾测试,那么它们应该被*cp
测试替换。