Solaris 编译器让我的 C 代码变得很奇怪

发布于 2024-10-30 09:46:46 字数 2172 浏览 3 评论 0原文

我正在尝试完成 C 编程科目的大学作业。

我已经在 MacBook 上完成了我的作业,并且我的代码按照预期完美运行。然而,我们的讲师告诉我们,我们所有的代码都将使用大学的 Solaris 10 Server 进行编译,并且我们被告知,如果您的代码不能在其上编译和运行,则会被扣分。

我们还被告知,我们的应用程序将由具有以下语法的标记进行编译:

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!)

任何人都可以帮我找出是什么导致这些奇怪的额外字符被从这个函数中吐出来 - 它让我头疼?

I am attempting to complete a college assignment, for a C Programming subject.

I have completed my assignment on my MacBook and my code works perfectly as it's supposed to. However, we've been told by our lecturer, that all our code will be compiled using the college Solaris 10 Server, and we've been told that if your code doesn't compile and run on it, marks will be deducted.

We've also been instructed that our app will be compiled by the markers with the following syntax:

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

and executed using:

./assign1

My code currently compiles without errors or warnings and executes properly. However, one of my functions doesn't work as expected on this Solaris box. The function is supposed to be our own implementation of a basic string sort - the user enters a string up to 40 characters long and its supposed to be converted to lowercase and sorted into alphabetical order with all non-alphabetical characters removed.

On my Mac, it outputs:

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

On the college's Solaris box, it outputs:

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

My function that does (most) of the output is:

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

A couple of notes however:

  • The function definition itself (the
    signature) is supplied by the
    lecturer, so names, return types,
    parameters etc cannot be changed.
    and we must use it as is (however we
    can do whatever we want inside it).

  • The code must be ANSI/C90 compliant
    (grr!)

Can anyone help me spot whats causing these weird extra characters from being spat out of this function - its doing my head in?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(4

女皇必胜 2024-11-06 09:46:46
int i,j,k;
char c = source[i++]; 
i = j = k = 0;

您在为 i 赋值之前就使用了它。您不能假设自动变量将被初始化为0

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

因为 cchar,所以它永远不能等于 EOF。不相关,但有一天你会看到这个错误:)你必须使用 int 来实现这个习惯用法:

int c;

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

你也在初始化之前使用 tempsort[]

        comp_c = tempsort[j];

您正在将大量数据写回到source[]数组中:

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

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

最后一点提示,每一个 (int) 转换都是无用的;编译器知道如何对 char 变量进行比较和算术运算。 :)

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

You're using i before you have assigned it a value. You cannot assume that auto variables will be initialized to 0.

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

Because c is a char, it cannot ever equal EOF. Unrelated, but someday you'll see this bug :) you have to use an int for this idiom:

int c;

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

You're using tempsort[] before it is initialized as well:

        comp_c = tempsort[j];

You are writing a lot of data back into the source[] array:

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

I hope the source[] array is guaranteed to be large enough to hold MAX_SORT_LENGTH data, rather than just-large-enough to hold a standard C string. Since this is probably a friendly professor, it is probably fine, but it is not an assumption I would make lightly.

And as a last hint, every one of those (int) casts is useless; the compiler knows how to compare and do arithmetic on char variables. :)

等你爱我 2024-11-06 09:46:46

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

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

您需要翻转这两行。

Not sure if this is the reason, but I noticed that you use i before it's properly initialized:

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

You'll want to flip those two lines around.

谎言月老 2024-11-06 09:46:46

也许错误在于没有将本地变量 i 初始化为零。

Perhaps the error is in not initialising the local var i to zero.

雾里花 2024-11-06 09:46:46

一些提示:

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

此外,请仔细查看循环上的边界条件。您确定没有访问超出数组末尾的内存吗?请记住,如果您有一个像 char x[10] 这样的数组,则有效值为 x[0]x[9]x[10] 超出范围。

A couple of hints:

  • if you have a program that's displaying different results on different systems, it's often an indication that it's using uninitialized data
  • you're passing the "-Wall" (print all warnings) flag to gcc, which is good, but you might want to be aware that gcc can do a better job of detecting (and warning about) uninitialized variables if you also use the "-O" (optimize) flag

Also, look closely at the boundary conditions on your loops. Are you sure you're not accessing memory beyond the end of your arrays? Remember that if you have an array like char x[10] valid values are x[0] through x[9]; x[10] is out of bounds.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文