我尝试使用此代码
通过分隔符将字符串拆分为两个字符串int indexOf(char *msg, char c) {
int i;
for (i = 0; msg[i] != '\0'; i++) {
if (msg[i] == c)
return i;
}
return -1;
}
char *substring(char *msg, int startIndex, int endIndex) {
int length = endIndex - startIndex;
char *input = (char *)malloc(length * sizeof(char) + 1);
int i;
for (i = startIndex; i != endIndex; i++) {
input[i - startIndex] = msg[i];
}
input[endIndex] = '\0';
return input;
}
在main
我有:
index = indexOf(msg, ':');
first = substring(line, 0, index - 1);
second = substring(line, index + 2, strlen(line));
当我用valgrind测试它时,此代码产生正确的输出。在第二个变量中分配的子字符串会产生错误。
此功能的问题在哪里?还有另一种方法将字符串拆分成两个字符串吗?
char *msg = readMessage(stdin);
index = indexOf(msg, '\n');
char *line, *first, *second;
line = substring(msg, 0, index);
结束valgrind Address 0x5203a52 is 5 bytes after a block of size 13 alloc'd
编辑:
还有另一个错误index = indexOf(line, ':');
现在,valgrind错误位于input[endIndex] = '\0';
行的子字符串中:
Invalid write of size 1
编辑:我的代码解决方案有两个错误
主中的
index = indexOf(msg, ':');
应该是
index = indexOf(line, ':');
和子字符串
input[endIndex] = '\0';
应该是
input[length] = '\0';
感谢所有
答案 0 :(得分:1)
index = indexOf(msg, ':');
^^^
line ?
下面
second = substring(line, index+2, strlen(line));
您认为该行长于索引+ 2。你应该检查一下以避免malloc
电话中的零。换句话说 - 如果分隔符是最后一个字符,则会遇到问题。
您应该添加malloc
if (!input)
{
// Print error message
exit(1);
}
顺便说一句 - 看看strdup
和memcpy
或strncpy
答案 1 :(得分:1)
您的代码中存在一些问题:
input[endIndex] = '\0';
使用错误的索引。它应该是input[length] = '\0';
main()
中,您不应对indexOf
的返回值做出隐含的假设。如果在:
中找不到line
,则发布的代码会调用未定义的行为:
这是一个更安全的版本:
int index = indexOf(line, ':');
if (index >= 0) {
// found the `:` separator
char *first = substring(line, 0, index);
if (line[index + 1] == ' ') {
index++; // skip the space after the :
}
char *second = substring(line, index + 1, strlen(line));
...
}
您可以使用strcspn()
代替indexOf
来提取测试次数较少的部分:
char *msg = readMessage(stdin);
size_t index = strcspn(msg, "\n");
char *line = substring(msg, 0, index);
...
strcspn()
返回字符数,但不包括其参数字符串中的字符数。如果字符存在,则返回与indexOf()
相同的值(size_t
类型而不是int
除外),如果字符串不是,则返回字符串的长度,这就是你想要的。