【问题标题】:Substring function in C with malloc returning incorrect valueC中的子字符串函数,malloc返回不正确的值
【发布时间】:2015-12-04 20:41:27
【问题描述】:

我正在 C 中为一阶逻辑公式实现解析器。要检查二进制连接公式(即格式为 (A BinaryConnective B)),我需要拆分字符串并检查 A 和 B 是否为公式。我使用 subString 函数完成了这项工作,并从 partone 和 parttwo(分别为 A 和 B)调用它:

char *partone(char *g) {
    //Given the formula (A*B) this returns A
    return subString(g, 1, binPosition(g));
}

char *parttwo(char *g) {
    //Given the formula (A*B) this returns B
    return subString(g, binPosition(g) + 1, strlen(g) - 1);
}

子串函数如下:

char *subString(char *g, int start, int end) {
    //the substring includes index start but does not include the end index.
    char *substr = malloc(sizeof(char)*(end - start));
    int i;
    for(i = 0; i < (end - start); i++) {
        substr[i] = g[start + i];
    }
    return substr;
}

当我传递除否定公式以外的任何函数时,这都有效(我们使用字符“-”表示否定)。例如,当我通过 (-X[xz]>X[yz]) 时,程序返回“不是公式”,但如果我在没有否定的情况下编写相同的内容,它会完美运行。问题是 partone() 返回的 substr 是“-X[xz]$”,其中 $ 可以是我认为之前存储在内存中的任何随机字符。任何想法为什么只在这种情况下发生这种情况?我是 C 新手,我到处都看过。

提前致谢。

【问题讨论】:

  • C 中的字符串需要 NUL 终止。您的 subString 函数不是 NUL 终止的,因此没有返回有效的 C 字符串。如果这不是问题,请提供Minimal Complete and Verifiable Example
  • .. 并且需要一个额外的内存字节来容纳它。
  • 如果end 是你需要的最后一个字符索引malloc(end - start + 2)
  • ... 和 sizeof char 始终为 1.. 并且应始终检查 malloc... 和 strlen(g) - 1 的返回值可能会给您一个负数。

标签: c string parsing logic substring


【解决方案1】:

您忘记了 subString 函数中的终止 NUL。你的 malloc 应该看起来像

char* substring = (char*)malloc (sizeof (char)*(end-start+1));

最后你需要用 0 终止结果:

substring [end-start]=0;

由于 c 中的数组是零索引的,我很惊讶你没有丢失 A 部分的前导“-”,因为 partone 调用 subString1 作为 start

编辑:在 C/C++ 中有很多用于字符串操作的内置函数。您应该使用它们,因为它们已经过测试和优化。多年来我没有这么多地使用 C,所以我不知道今天 C++11 中合适的方法是什么,但谷歌可能会告诉你。

编辑:正如 chux 所指出的,您的 end 参数的含义并不完全清楚。所以你需要检查parttwo中的strlen (g)-1subString中的循环条件,并在我的malloc语句中增加到+2

【讨论】:

  • 是的,它们是零索引的,但是传递的公式是 (A*B) 的形式,所以我不需要 ( 字符。谢谢,这很有帮助
【解决方案2】:

OP 对startend 的使用尚未正式化,但我假设它们是所需子字符串的第一个和最后一个字符的字符串的索引。

回想一下,在 C 中,数组索引以 0 开头,因为 g[0] 是存储在 g 处的字符串的第一个字符。

如果是这种情况,代码需要分配end - start + 1 + 1空间并确保分配的字符数组末尾有一个空字符'\0'

char *subString(const char *g, int start, int end) {
  if (end < start || start < 0) {
    return NULL;
  }
  size_t size = 2u + end - start;
  char *substr = malloc(size);
  if (substr) {
    int i;
    for(i = 0; i < (end - start); i++) {
      substr[i] = g[start + i];
    }
    substr[i] = '\0';
  }
  return substr;
}

其他可能的简化/改进

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2020-10-10
    • 2013-03-05
    • 1970-01-01
    • 2020-07-02
    • 2014-12-12
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多