打印char数组时出现意外的字符

时间:2016-04-24 19:53:02

标签: c

我正在尝试构建一个cron表达式解析器

我有以下方法(正在进行中):

Cron parseCron(char* cronStr) {
  char *dup = strdup(cronStr);
  char* p;
  char* cronAtoms[5];
  int i = 0;
  p = strtok(dup, " ");
  while(p != NULL){
    p = strtok(NULL, " ");
    cronAtoms[i] = p;
    i++;

  }
  return generateCron(cronAtoms);

}

和这一个:

Cron generateCron(char **cronAtoms){
  Cron cron;
  for(int i = 0; i < 5; i++) {
    printf("%s\n", cronAtoms[i]);
  }
  return cron;
}

输入字符串为"* * * * *"  当我在这里打印结果时,得到的结果是:

*
*
*
*
@

我不得不承认我有点惊讶,但我想我理解为什么。存储在cronAtoms数组中的最后一个指针可能包含NULL终止字符,或者可能包含相邻内存中的某些内容。我不是C专家,所以我完全有可能将自己的假设弄错了。

更重要的是,我想知道一种傻瓜式的方式正确地提取最后一个角色(有&#34; *&#34;而不是&#34; @&#34;)

1 个答案:

答案 0 :(得分:0)

您的逻辑是错误的,如果您将代码应用于包含可以彼此区分的字段的输入,那么这对您来说是显而易见的。

这......

p = strtok(dup, " ");

...导致p指向字符串中的第一个标记。然后当你继续......

while(p != NULL){
  p = strtok(NULL, " ");

...您将p指向 next 令牌,如果有的话,会丢失第一个。

这个位或多或少都可以......

  cronAtoms[i] = p;
  i++;

...但是如果输入超过五个字段(从不假设您的输入有效),它不会防止超出数组的范围。

此外,您不会初始化cronAtoms的元素,因此如果在分配所有字段之前用完字段(就像在这种情况下那样,因为忽略了第一个字段) ,或者你可能使用无效输入)然后当generateCron()检查它们时,未写入的元素包含垃圾。

另外,strdup()分配你有义务释放的内存。如果你不这样做 - 你不这样做 - 那么你的程序会泄漏那个记忆。