C中的子串函数,malloc返回不正确的值

时间:2015-12-04 20:41:27

标签: c string parsing logic substring

我在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]&gt; X [yz])时,程序返回“Not a Formula”,但如果我在没有否定的情况下编写相同的内容,则它会完美地运行。问题是为partone()返回的substr是“-X [xz] $”,其中$可以是我认为之前存储在内存中的任何随机字符。任何想法为什么这种情况只发生在这种情况下?我是C的新手,我到处寻找。

提前致谢。

2 个答案:

答案 0 :(得分:1)

您忘记了char* substring = (char*)malloc (sizeof (char)*(end-start+1)); 功能中的终止NUL。你的malloc看起来应该是

substring [end-start]=0;

最后你需要用0结束结果:

partone

由于c中的数组是零索引的,我很惊讶您不会丢失A部分的前导“ - ”,因为subString使用1调用startend

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

编辑:正如chux指出的那样,strlen (g)-1参数的含义并不完全清楚。因此,您需要检查parttwo中的subString+2中的循环条件,并在malloc语句中增加到package login.test; import java.io.File; import java.io.FileInputStream; public class QTI_Excelaccess { public static void main(String [] args){ //verify what the working directory is String curDir = System.getProperty("user.dir"); System.out.println("Working Directory is: "+curDir); //verify the file is recognized within within the code File f = new File("C:\\\\Users\\wes\\workspace\\QTI_crud\\values.xlsx"); if (f.exists() && !f.isDirectory()){ System.out.println("Yes, File does exist"); } else { System.out.println("File does not exist"); } //Assign the file to src File src = new File("C:\\\\Users\\wes\\workspace\\QTI_crud\\values.xlsx"); System.out.println("SRC is now: "+src); //Get Absolute Path of the File System.out.println(src.getAbsolutePath()); FileInputStream fis = new FileInputStream(src); }*

答案 1 :(得分:1)

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

可能的其他简化/改进