Strange glitches in my C sorting program

Click For Summary

Discussion Overview

The discussion revolves around issues encountered in a C sorting program, specifically related to user input handling and program termination. Participants explore problems with a menu function, unexpected program exits, and segmentation faults during sorting operations.

Discussion Character

  • Homework-related
  • Technical explanation
  • Debugging
  • Exploratory

Main Points Raised

  • One participant describes issues with a menu function where a "Try again" message is printed twice, suggesting that the input handling may be flawed due to how characters are processed.
  • Another participant speculates that the program's exit status might not indicate an error but rather a normal termination, questioning the meaning of the exit code reported by the operating system.
  • Concerns are raised about how to handle the carriage return character that follows user input, with suggestions to flush the input buffer or call getchar() again without using the returned character.
  • A participant identifies a segmentation fault occurring in the bubble sort function, suspecting that the arrLen function may be returning an incorrect length due to the absence of a terminating character in the input array.
  • There is a discussion about the discrepancy in the argc value when running the program in different environments, with one participant realizing it was a mistake on their part.
  • Another participant explains that arrays decay to pointers when passed to functions, leading to confusion about the size of the array within the bubbleSort function.

Areas of Agreement / Disagreement

Participants express varying viewpoints on the causes of the program's issues, with no consensus reached on the best solutions. Some participants agree on the need for debugging techniques, while others propose different methods for handling input and array sizes.

Contextual Notes

Limitations include the potential for undefined behavior due to improper handling of array lengths and input characters. The discussion highlights the challenges of managing memory and input in C programming.

Who May Find This Useful

This discussion may be useful for students and programmers dealing with C language input handling, debugging segmentation faults, and understanding array behavior in function calls.

Bob Busby
Messages
44
Reaction score
0

Homework Statement


I have to write a program that takes in a file that looks like this:

3424: 313
4334: 543
etc.

and sorts the numbers on the write. Everything for getting the file into an array was done for me so I know it's correct. I'm having two strange problems. First, whenever I'm checking user input for choosing which algorithm to use, my "Try again message is always printed twice. I traced it and inexplicably the while loop always goes through twice.

Second, the sort works fine but every time it's time for the program to finish the console window errors out and says "blah.exe has stopped working."

Homework Equations



Code:
This program loads, sorts in decending order, and prints 100 numbers. */

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

#define TRUE 1
#define FALSE 0

void swap(int *x, int *y);
int arrLen(int *arr);
char menu();
void bubbleSort(int *arr);

int main(int argc, char *argv[]) {
   int	Nums[100];
   int	NumNums, N;
   char ans;

   if (argc != 2) {
     printf("usage: ./P1-2 valuefile\n");
     exit(1);
   }
   NumNums = Load_Mem(*++argv, Nums);
   if (NumNums != 100) {
      printf("valuefiles must contain 100 entries\n");
      exit(1);
   }

   /* Your program goes here */
   ans = menu();
   bubbleSort(Nums); 

   for(N = 0; N < NumNums; N++)           /* don't change this print loop */
      printf("%4d: %8d\n", N, Nums[N]);
      
      //ans = getchar();
      return 0;
}

/* Swaps two ints in an array */
void swap(int *x, int *y)
{
   int temp = *x;
   *x = *y;
   *y = temp;
}

int arrLen(int *arr)
{
    int i = 0;
    while(*(arr++)) i++;
    return i;     
}

char menu()
{
     int i;
     char c = ' ';
     for(i = 0; i < 50; i++) printf("-");
     printf("\nChoose your preferred sorting method:\n");
     printf(" 'b' - Bubble Sort\n");
     printf(" 'q' - Quick Sort\n");
     do {
        c = getchar();
        printf("Try again\n");
     } while(c != 'b' && c != 'q');
     return c;
}

/* Performs a version of bubble sort */
void bubbleSort(int *arr)
{
   
   int i, j, len, n, swapped = TRUE;
   len = arrLen(arr);
   n = len;

   while(swapped)
   {
    swapped = FALSE;
	for(j = 0; j < len-1; j++)
	{
	   if(arr[j] > arr[j+1])
	   {
	      swap(&arr[j],&arr[j+1]);
	      swapped = TRUE;
       }
    }
 }
	
    
}

/* This routine loads in up to 100 newline delimited integers from
a named file in the local directory. The values are placed in the passed integer array. The number of input integers is returned. */

int Load_Mem(char *InputFileName, int IntArray[]) {
   int	N, Addr, Value, NumVals;
   FILE	*FP;

   FP = fopen(InputFileName, "r");
   if (FP == NULL) {
      printf("%s could not be opened; check the filename\n", InputFileName);
      return 0;
   } else {
      for (N=0; N < 100; N++) {
         NumVals = fscanf(FP, "%d: %d", &Addr, &Value);
         if (NumVals == 2)
            IntArray[N] = Value;
         else
            break;
      }
      fclose(FP);
      return N;
   }
}

The Attempt at a Solution



I've tried tracing through it with gdb and two different IDE's but with no luck. Any help you can offer will be much appreciated! :wink:
 
Physics news on Phys.org
When the menu function is executing, what are you typing in the console? If you are entering 'C' instead of 'c', the while condition at the bottom of your do ... while loop is false, so the loop starts up again. The second time through the loop it won't let you do input, because getchar() is processing the 2nd character you typed - the ENTER key.

As for your second error, it might not be an error at all. When your program hits the return 0 statement, the program will quit, and maybe the OS is just reporting that your program has quit. I'm just guessing on this, and could be wrong.

It would be helpful to see a screen shot with the exact message.
 
Thanks for the help.:approve:

So the return character is necessary to finish the input how do I get rid of it and only it before the while loops condition is checked?

Here's a picture of what happens when the program finishes, although I don't think it will help much. Also, I don't think it's a problem with the OS because when I run it, it exits with status code 1.

Also, I have another question. Whenever I run the program through the command prompt using the command: P1-1 100nums.txt argc equals 1 and the whole thing ends early. What's the reason for the discrepancy? When I run it by clicking and dragging onto the executable argc == 2 and when I run it with DevC++ argc ==2? Thanks again!

[PLAIN]http://dl.dropbox.com/u/7264839/Help/sortErr.PNG

[PLAIN]http://dl.dropbox.com/u/7264839/Help/gdb.PNG
 
Last edited by a moderator:
The nicest way to get rid of the extra CR (or carriage return) character, is to flush the input buffer, like so: fflush(stdin);

Another way is to call getchar() again, but don't do anything with the character that is returned.

Bob Busby said:
Also, I have another question. Whenever I run the program through the command prompt using the command: P1-1 100nums.txt argc equals 1 and the whole thing ends early. What's the reason for the discrepancy?
I don't see why this is happening. If the command line looks like

C:\users\grayson\Desktop\P1-1.exe 100nums.txt

argc should be 2
and argv[1] should be the string 100nums.txt

You could test this outside the debugger by inserting a printf statement near the top of your main() function, just before you check to see if argc is 2.

Code:
printf("Arg count is %d.\n", argc);
printf("Argv[1] is %s.\n", argv[1]);
if (argc != 2) {
... etc.
 
OK, the argc problem was just a stupid mistake on my part, but I still don't see why the program exits with code 1 at the end. By the time the array is sorted (which is clearly shown) all "exit(1)" statements have been passed and the only return statement left is the final "return 0;"

EDIT: Okay, I retried it with gdb and found something new. It says I'm getting a segmentation fault. I'll look into it more but if you have any idea what this could be from I'd appreciate the input.

[PLAIN]http://dl.dropbox.com/u/7264839/Help/seg.PNG
 
Last edited by a moderator:
Your program exits with code 1 because of the exit(1) statement in two of your if statements in main.

For the segmentation fault, there might be something flaky in your Load_Mem routine. Since you aren't able to figure out what's going wrong using a debugger, you can use the tried and true fallback technique of inserting printf statements in each of your routines. The output you get will tell your which routines are working, and you can see the last thing that happened before you get a segmentation fault (which usually occurs when you try to store something at an inappropriate address).
 
OK, I found the problem.

My arrLen function was returning too many elements. I have to find the length of the input array, which I wrote my general purpose function for counting the length of an array. The problem was when Load_Mem() (which I didn't write) didn't put a terminating character at the end of the array, which led to my arrLen() function counting too high which led to a segmentation fault in bubbleSort().

I just have one more question on some weirdness. Whenever I find the length of Nums (array of ints) with sizeof(Nums)/sizeof(int) in main I get the correct answer (100), but after I passed it to bubbleSort and called sizeof(arr)/sizeof(int) I get 1,m which is completely off. Any ideas as to why that happens?
 
Bob Busby said:
I just have one more question on some weirdness. Whenever I find the length of Nums (array of ints) with sizeof(Nums)/sizeof(int) in main I get the correct answer (100), but after I passed it to bubbleSort and called sizeof(arr)/sizeof(int) I get 1,m which is completely off. Any ideas as to why that happens?

Arrays "decay" to pointers. The type of the argument to your bubble sort function is pointer to int and not an array. The size of a pointer does not indicate the size of an array.

Arrays in C are not http://en.wikipedia.org/wiki/First-class_object" .

Your bubble sort should take at least two parameters. The first should point to the first element of the data to be sorted, as the parameter "arr" would. The second could be the end of the half open interval (a pointer to one past the last actual element in the array to be sorted), or some integer type indicating the size of the array.
 
Last edited by a moderator:

Similar threads

  • · Replies 4 ·
Replies
4
Views
2K
  • · Replies 18 ·
Replies
18
Views
3K
  • · Replies 3 ·
Replies
3
Views
2K
  • · Replies 3 ·
Replies
3
Views
2K
  • · Replies 4 ·
Replies
4
Views
2K
  • · Replies 3 ·
Replies
3
Views
2K
  • · Replies 7 ·
Replies
7
Views
3K
  • · Replies 1 ·
Replies
1
Views
3K
  • · Replies 11 ·
Replies
11
Views
2K
  • · Replies 1 ·
Replies
1
Views
2K