# Strange glitches in my C sorting program

## 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);
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);
}
if (NumNums != 100) {
printf("valuefiles must contain 100 entries\n");
exit(1);
}

/* Your program goes here */
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;
}

{
int i;
char c = ' ';
for(i = 0; i < 50; i++) printf("-");
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[]) {
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!

Mark44
Mentor
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.

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 [Broken]

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

Last edited by a moderator:
Mark44
Mentor
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 [Broken]

Last edited by a moderator:
Mark44
Mentor
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?

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" [Broken].

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: