Solaris编译器使我的C代码行为很奇怪

时间:2011-04-05 04:29:59

标签: c solaris

我正在尝试为C编程主题完成大学任务。

我已经在我的MacBook上完成了我的任务,我的代码完全符合预期。但是,我们的讲师告诉我们,所有代码都将使用大学Solaris 10 Server进行编译,并且我们被告知如果您的代码没有编译并在其上运行,则会扣除标记。 / p>

我们还被告知我们的应用程序将使用以下语法编译:

gcc -ansi -Wall -pedantic assign1.c -lm -o assign1

并执行使用:

./assign1

我的代码目前编译时没有错误或警告并正确执行。但是,我的某个功能在此Solaris机器上无法正常工作。该函数应该是我们自己的基本字符串排序实现 - 用户输入一个长度最多为40个字符的字符串,它应该被转换为小写并按字母顺序排序,并删除所有非字母字符。

在我的Mac上,输出:

Enter a string (1-40 characters): asdfghjkl
Output: adfghjkls

在学院的Solaris盒子上,输出:

Enter a string (1-40 characters): asdfghjkl
Output: aa#?dfghjkls

我(大部分)输出的功能是:

void sortLine(int *optionStats, char* source)
{
   char tempsort[MAX_SORT_LENGTH + 1];
   char comp_c;
   int i,j,k;
   char c = source[i++]; 
   i = j = k = 0;
   optionStats[2]++;
   while (c != '\n' && c != '\0' && c != EOF) {
      /* convert uppercase characters to lowercase */
      if ((int)c >= (int)'A' && (int)c <= (int)'Z') 
         c = c + ((int)'a' - (int)'A');
      /* if the character is alphabeic then sort it else skip it */
      if ((int)c <= (int)'z' && (int)c >= (int)'a') {
         for (j = 0; j <= MAX_SORT_LENGTH + 1; j++) {
            comp_c = tempsort[j];
            if (comp_c == '\n' || comp_c == '\0' || comp_c == EOF) {
               tempsort[j] = c;
               break;
            }
            if ((int)c <= (int)comp_c) {
               for (k = MAX_SORT_LENGTH + 1; k > j; k--) {
                  tempsort[k] = tempsort[k - 1];
               }
               tempsort[j] = c;
               break;
            }
         }
      }
      c = source[i++];
   }
   /* copy the sorted temporary array into the source array */
   for (i = 0; i <= MAX_SORT_LENGTH + 1; i++) {
      source[i] = tempsort[i];
   }
}

然而,有几点注意事项:

  • 函数定义本身( 签名)由提供 讲师,所以姓名,回报类型, 参数等不能改变。 我们必须按原样使用它(但是我们 可以做任何我们想做的事情。)

  • 代码必须符合ANSI / C90标准 (GRR!)

任何人都可以帮我发现什么导致这些奇怪的额外角色被这个函数吐出来 - 它正在我的脑袋里?

4 个答案:

答案 0 :(得分:5)

int i,j,k;
char c = source[i++]; 
i = j = k = 0;

您在为其分配值之前使用i。您不能假设自动变量将初始化为0

while (c != '\n' && c != '\0' && c != EOF) {

因为cchar,所以它不能等于EOF。不相关,但有一天你会看到这个bug :)你必须使用int这个成语:

int c;

while((c=getchar()) != EOF) {
    /* process c */
}

您在初始化之前使用tempsort[]

        comp_c = tempsort[j];

您正在将 lot 数据写回source[]数组:

for (i = 0; i <= MAX_SORT_LENGTH + 1; i++) {
   source[i] = tempsort[i];
}

我希望source[]数组保证足够大以容纳MAX_SORT_LENGTH数据,而不是仅仅足够大以容纳标准C字符串。因为这可能是一位友好的教授,所以可能很好,但这不是我会轻易做出的假设。

作为最后的暗示,这些(int)演员中的每一个都是无用的;编译器知道如何比较和对char变量进行算术运算。 :)

答案 1 :(得分:3)

不确定这是否是原因,但我注意到你在正确初始化之前使用了我:

char c = source[i++]; 
i = j = k = 0;

你想要翻转这两行。

答案 2 :(得分:2)

错误可能是没有将局部变量i初始化为零。

答案 3 :(得分:2)

一些提示:

  • 如果您的程序在不同的系统上显示不同的结果,则通常表明它使用的是未初始化的数据
  • 你将“-Wall”(打印所有警告)标志传递给gcc,这很好,但你可能想知道gcc可以更好地检测(并警告)未初始化的变量也使用“-O”(优化)标志

另外,仔细观察循环的边界条件。你确定你没有访问阵列末尾的内存吗?请记住,如果您有一个类似char x[10]的数组,则有效值为x[0]x[9]; x[10]超出范围。