c - 通过分隔符将字符串拆分为两个字符串

标签 c string split malloc

我尝试用这段代码将一个字符串分成两个字符串

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';

感谢大家

最佳答案

您的代码中存在一些问题:

  • 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),它返回字符串的长度(如果不是),这就是您想要的。

关于c - 通过分隔符将字符串拆分为两个字符串,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/41075996/

相关文章:

c - C 中的 puts 和 printf

C:无法在不丢失另一个的情况下读取 2 个管道文件描述符

jquery - 使用 JQuery 将新属性添加到 HTML 字符串

c - "Deleting"来自 C 中的数组

java - 使用 Java split() 方法将 XML 字符串拆分为多个 XML 文档

javascript - 如果对象属性具有特定分隔符,如何拆分 JavaScript 数组元素

c - 解析不带编码特殊字符的rtf文件

c - C 中的哈希表(查找每个单词的频率)

python - 字符串列表,获取n个元素的公共(public)子串,Python

java - java 1.6 中 String.split 的行为?