【问题标题】:C code runs in Eclipse-Kepler but fails to run in Codeblocks IDEC 代码在 Eclipse-Kepler 中运行,但无法在 Codeblocks IDE 中运行
【发布时间】:2013-11-16 19:32:00
【问题描述】:

我是 C 编程的新手,也是 Stackoverflow 的新手。

我有一些在 Eclipse Kepler (Java EE IDE) 中编译和运行的 c 代码;我为 c 安装了 C/C++ 插件和 Cygwin Gcc 编译器。 在 Eclipse IDE 中一切正常;但是,当我的朋友尝试在他的 Codeblocks IDE 上运行相同的代码时,他没有得到任何输出。在某些时候,他遇到了一些分段错误,我们后来了解到这是由于我们的程序访问了不属于我们程序的内存空间。

Codeblocks IDE 使用的是 Gcc 编译器而不是 cygwin gcc,但我认为它们不会导致此类问题。

我知道 C 语言非常原始且非标准化,但为什么我的代码会在 eclipse 中使用 cygwin-gcc 编译器运行,但不能在 Codeblocks IDE 中使用 gcc 编译器运行?

请帮忙,这对我们的课堂项目很重要。

谢谢大家。

[编辑] 我们的代码有点大,无法粘贴在这里,但这里有一个示例代码,说明在 Eclipse 中可以成功运行但在代码块中失败,如果您有代码块,请自行尝试:

#include <stdio.h>
#include <stdlib.h>
#include <math.h>
#include <string.h>


int main(void) {
    char *traceEntry1;
    FILE *ifp;

    traceEntry1 = malloc(200*sizeof(char));
    ifp = fopen("./program.txt", "r");

    while (fgets(traceEntry1, 75, ifp)) 
      printf("String input is %s \n", traceEntry1);
    fclose(ifp);
}

它根本不会在代码块中提供任何输出,有时只会导致分段错误错误。

我不知道问题是什么。

我们需要您的帮助,在此先感谢。

【问题讨论】:

  • 如果您的代码包含导致未定义行为的错误,它可能会在某些环境中工作而在其他环境中失败。您需要发布代码以获得更详细的反馈。
  • “我知道 C 是非常原始且非标准化的” C 非常标准化。问题是除非你熟悉标准,否则很容易发现自己处于非标准领域。而且,考虑到 C 相对于更低级别的语言的表达能力以及它在过去 40 年中管理世界的能力,我认为将其称为原始语言并不公平:)。
  • @Corbin,如果我让你不高兴,我很抱歉。我的意思是说相对于其他语言(如 Java)的“原始”,它是(1)可从一台机器移植到另一台机器,而不需要 C 所没有的额外努力;和 (2) 以及完整的函数库,可帮助您提高工作效率。 C 确实更接近机器,因此速度快了几毫秒,但它对编译器和运行时错误的支持是不可原谅的。话虽这么说,C 对于掌握它的人来说确实是一个非常强大的工具,但对于新手来说却是这样一个学习曲线,我就是这样,因此用 C 做这些项目,这样我就可以变得更好。
  • 尝试添加 "printf("%s\n", strerror(errno));"就在你打电话给 ifp 之后。您将需要包含 。 (此外,您应该始终检查 fopen 是否返回 NULL)。您还可以使用 getcwd 来确保您的程序在正确的目录中运行。
  • 谢谢 Noshenim,我试过了,但还是没有。还有其他想法吗?您是否成功地在代码块中运行了那段代码?不过,你给了我一个更好的想法来调试这个程序,谢谢。

标签: c eclipse gcc codeblocks


【解决方案1】:

始终测试所有(相关)调用的结果。 “相关”至少是那些在调用失败时返回不可用结果的调用。

对于 OP 的代码,它们是:

  • malloc()
  • fopen()
  • fclose()

OP 代码的保存版本可能如下所示:

#include <stdio.h>
#include <stdlib.h>

int main(void) 
{
  int result = EXIT_SUCCESS; /* Be optimistic. */
  char * traceEntry1 = NULL; /* Always initialise your variables, you might remove this during the optimisation phase later (if ever) */
  FILE * ifp = NULL;   /* Always initialise your variables, you might remove this during the optimisation phase later (if ever) */

  traceEntry1 = malloc(200 * sizeof(*traceEntry1)); /* sizeof(char) is always 1. 
              Using the dereferenced target (traceEntry1) on the other hand makes this 
              line of code robust against modifications of the target's type declaration. */ 
  if (NULL == traceEntry1)
  {
    perror("malloc() failed"); /* Log error. Never ignore useful and even free informaton. */
    result = EXIT_FAILURE;  /* Flag error and ... */
    goto lblExit;  /* ... leave via the one and only exit point. */
  }

  ifp = fopen("./program.txt", "r");
  if (NULL == ifp)
  {
    perror("fopen() failed"); /* Log error. Never ignore useful and even free informaton. */
    result = EXIT_FAILURE; /* Flag error ... */
    goto lblExit;  /* ... and leave via the one and only exit point. */
  }

  while (fgets(traceEntry1, 75, ifp)) /* Why 75? Why not 200 * sizeof(*traceEntry1) 
                                         as that's what was allocated to traceEntr1? */
  {
    printf("String input is %s \n", traceEntry1);
  }

  if (EOF == fclose(ifp))
  {
    perror("fclose() failed");
    /* Be tolerant as no poisened results are returned. So do not flag error. It's logged however. */
  }

lblExit: /* Only have one exit point. So there is no need to code the clean-up twice. */

  free(traceEntry1); /* Always clean up, free what you allocated. */

  return result; /* Return the outcome of this exercise. */
}

【讨论】:

  • 非常感谢,我会测试一下,如果它有效,我会立即给你点赞,因为其他有类似问题的人会来这里。但再次非常感谢这个非常详尽且更有帮助的答案。我应该在今天午夜之前回复你,谢谢。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2014-04-17
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多