开发者

Solaris Compiler Making my C Code Act Weird

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 y开发者_如何学JAVAour 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?


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. :)


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.


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


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.

0

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜