我尝试用这段代码将一个字符串分成两个字符串
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);
end valgrind 地址 0x5203a52 是分配大小为 13 的 block 之后的 5 个字节
编辑:
还有另一个错误
index = indexOf(line, ':');
现在 valgrind 错误出现在 input[endIndex] = '\0';
行的子字符串中:
Invalid write of size 1
编辑:我的代码有两个错误的解决方案
主要
index = indexOf(msg, ':');
应该是
index = indexOf(line, ':');
在子串中
input[endIndex] = '\0';
应该是
input[length] = '\0';
感谢大家
您的代码中存在一些问题:
这是一个更安全的版本:
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
),它返回字符串的长度(如果不是),这就是您想要的。
我是一名优秀的程序员,十分优秀!