【发布时间】:2016-09-22 01:47:53
【问题描述】:
免责声明:这是家庭作业的一部分,但不是全部作业。
我的任务是创建一个“tokenizer”对象,该对象通过在每次调用 TKGetNextToken 时返回一次来检索由空格分隔的令牌,并对返回的令牌执行一系列操作。
但是,TKGetNextToken 函数的行为并不正常。应该发生的是:
- 遍历输入字符串,直到找到非空白字符。
- 继续遍历输入字符串,直到遇到空格或 NULL(指示字符串的结尾),然后将字符添加到新的 c 字符串中
- 如果遇到空格,则返回 c 字符串,并将字符串中的当前位置保存在 TokenizerT 结构中。
- 如果遇到 NULL,则返回 c 字符串,并将 NULL 存储在 TokenizerT 结构中,以便随后对 TKGetNextToken 的所有调用都返回 NULL。
但是,该函数不会在字符串的末尾停止,而是直接从字符串的末尾吹过并打印出内存中的所有内容,直到程序崩溃。我不知道为什么会这样。
这里是代码
#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
【问题讨论】:
-
"函数不会在字符串的末尾停止" --> 没有代码可以测试字符串的结尾。
标签: c string segmentation-fault